Spring 6【p命名空间和c命名空间】(五)-全面详解(学习总结---从入门到深化)

news2024/11/28 8:38:04

 

目录

十、p命名空间和c命名空间


 

十、p命名空间和c命名空间

老版本的Spring框架XML配置文件是使用DTD的,但是在目前Spring框架中多使用XSD。因为在XSD扩 展支持。这也是为什么Spring框架配置文件由原来的DTD更换成XML Schema,毕竟Spring现在是模块化了,用哪个模块,XML文件支持这个模块的配置会更好。

 

 1. DTD 和 XSD复习

Spring Framework在老版本时配置文件支持DTD,但是随着Spring框架项目拆分,配置文件也变为 XSD。下面我们来复习一下DTD和XSD。

 DTD 复习

DTD (Document Type Definition,文档类型定义)属于XML文档的一部分。作用是对XML文档内容进行校验。

 缺点:

1、独立语法,没有使用XML语法。例如:spring-beans.dtd文件部分截图

 2、支持类型较少。只有(#PCDATA)类似Java中的字符串类型。

3、扩展能力差。一个XML文件只能导入一个DTD。当需要扩展,必须更换整个DTD文件。例如 MyBatis框架配置文件就是用的是DTD。

 XSD复习

XSD(XML Schemas Definition,XML结构定义)属于DTD的升级版。相对DTD来说XSD具备更多优点。

1、XSD本身就是一个XML文档,所以使用XML的语法。例如:spring-beans.xsd截图

2、 支持类型较多。支持简单数据类型和复杂类型。

简单类型

 复杂类型

 支持扩展。只需要在 xsi:schemaLocation 中添加一组键值对。其中key表示XSD文件名称,value 表示XSD文件路径。如果需要添加新的XSD粘贴到这里面就可以,但需要保证Key和Value不分家 (中间没有其他键值对)。

 

 支持命名空间.XSD支持对标签和标签属性的扩展。命名空间作为根标签(beans)的一个属性。 语法为 xmlns:自定名称="key"

使用时为

<标签 自定名称:xxx=""> 或 <自定义名称:标签名 >

 大部分命名空间的key需要与 xsi:schemaLocation 中键值对的key对应。但是部分内容没有xsd文 件,因为这个命名空间没有内容限制,而是通过反射根据类的内容而决定。下面学习的p命名空间 和c命名空间就是没有添加xsd键值对的实际应用。

 2. p命名空间

Spring 框架提供了p命名空间,属于 <property> Setter注入的简写方式。所以p就是property的缩写。 但是要注意,p命名空间是为了代替 <property name="" ref=""/><property name="" value=""> 这两种写法。

使用时需要在xml文件中导入p命名空间。

xmlns: 代表Schema的命名空间的意思。

p是命名空间的名称。可以修改的。但是为了增加可读性,官方叫什么,我们就跟着叫什么。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

我们重新建立一个类,进行测试

public class Animate {
     private int id;
     private String name;
     // 省略getter、setter、构造方法
}

在没有使用p命名空间时

<bean id="animate" class="com.tong.pojo.Animate">
     <property index="0" value="1"></property>
     <property name="name" value="毛毛"></property>
</bean>

使用p命名空间后的简写方式。

语法:p:属性名="值" 或 p:_序号="值"

<bean id="animate2" class="com.tong.pojo.Animate" p:_0="2" p:name="旺财"></bean>

3.c命名空间

Spring 框架提供了c命名空间,属于<constructor-args> 构造注入的简写方式。所以c就是constructor 的缩写。

但是要注意,c命名空间只提供了<constructor-args> 中name和index属性等效效果,而且还不能混 合使用。也就是说当构造方法比较多,且无法通过一个属性就能明确确认构造方法时,不要使用c命名空间。

c命名空间需要在配置文件中添加新的Schema配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

在没有使用c命名空间时

<bean id="animate" class="com.tong.pojo.Animate">
      <constructor-arg name="id" value="1"></constructor-arg>
      <constructor-arg index="1" value="毛毛"></constructor-arg>
</bean>

在使用c命名空间简写后的写法。

语法:c:属性名="值" 或 c:_序号="值"

<bean id="animate2" class="com.tong.pojo.Animate" c:id="2" c:_1="旺财" ></bean>

4.util命名空间

util命名空间从Spring Framework 2.0开始就有了。但是作为Spring框架支持的命名空间,还是有必要 给小伙伴们介绍一下。

util命名空间主要的作用简化定义集合类型Bean、常量类型Bean的语法。实现快速给特定类型定义为 Bean。像这种给特定类型单独定义成Bean是为了这个类型值实现复用,其他Bean可以通过ref直接引用,但是util命名空间的作用是简化定义的语法,而不是为了复用。

想要使用util命名空间,必须在Spring框架配置文件中导入对应的xsd文件路径及命名空间。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       https://www.springframework.org/schema/util/spring-util.xsd">
</beans>

导入命名空间后,可以发现util一共支持6个标签,分别代表的含义:

1、util:constant 定义常量 util:list 定义list集合

2、util:map 定义map集合 util:properties 定义属性文件

3、util:property-path 使用连缀写法给关联Bean属性赋值。

4、util:set 定义set集合

4.1 util:constant 

先创建一个类,类中包含一个静态属性com.tong.pojo.MyUtil

public class MyUtil {
     public static String NAME="smallmming";
}

当我们想要把上面这个静态变量定义为一个Bean时,必须借助FieldRetrievingFactoryBean才能定义。

<bean id="myName" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
     <property name="staticField" value="com.tong.pojo.MyUtil.NAME"></property>
</bean>

上面的写法也有一种简写方式

<bean id="com.tong.pojo.MyUtil.NAME" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
</bean>

简写方式已经比较简单了,但是最简单的方式还是使用util命名空间。不需要再去记忆 FieldRetrievingFactoryBean这个类。

<util:constant static-field="com.tong.pojo.MyUtil.NAME"></util:constant>

如果定义完成后,想要把常量Bean注入到其他类属性中

先定义一个类com.tong.pojo.Demo

public class Demo {
   private String name;
   public String getName() {
         return name;
   }
   public void setName(String name) {
         this.name = name;
      }
@Override
public String toString() {
      return "Demo{" +
           "name='" + name + '\'' +
        '}';
     }
}

修改配置文件,给util:constant定义一个id,然后让Demo的name属性ref这个id值。

<util:constant static-field="com.tong.pojo.MyUtil.NAME" id="myUtilName"></util:constant>

<bean id="demo" class="com.tong.pojo.Demo">
       <property name="name" ref="myUtilName"></property>
</bean>

编写测试

@Test
void util(){
      ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext5.xml");
      Demo demo = ac.getBean("demo", Demo.class);
      System.out.println(demo);
}

4.2 util:list

当我们想要定义一个List类型Bean时,必须借助ListFactoryBean

<bean id="myList" class="org.springframework.beans.factory.config.ListFactoryBean">
      <property name="sourceList">
           <list>
               <value>1</value>
               <value>2</value>
               <value>3</value>
           </list>
      </property>
</bean>

如果不想要去记忆ListFactoryBean,可以使用util命名空间。

      1、 list-class 定义List接口的实现类是谁。默认是ArrayList。

      2、value-type 定义List的值类型,即泛型类型。否则由Spring框架判断。

注意:对于初学者,很容易在util:list里面又套一个 <list>标签,如果写上了,相当于 List<List<String>>

<util:list id="myUtilList" list-class="java.util.LinkedList" value-type="java.lang.String">
      <value>a</value>
      <value>b</value>
      <value>c</value>
</util:list>

 相同道理如果想要把定义成List的Bean注入给某个Bean的属性,依然使用ref引用id即可。

修改Demo类,添加list属性,生成getter、setter方法,和toString()方法

 

public class Demo {
     private String name;
     private List<?> list;

     public List<?> getList() {
          return list;
     }

     public void setList(List<?> list) {
          this.list = list;
     }

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     @Override
     public String toString() {
           return "Demo{" + "name='" + name + '\'' + ", list=" + list +'}';
      }
}

修改配置文件中Demo的bean

<bean id="demo" class="com.tong.pojo.Demo">
     <property name="name" ref="myUtilName"></property>
     <property name="list" ref="myUtilList"></property>
</bean>

 运行结果,可以发现正常输出list属性值。

4.3 util:map

正常定义一个Map类型的Bean需要借助MapFactoryBean

<bean id="myMap"  class="org.springframework.beans.factory.config.MapFactoryBean">
     <property name="sourceMap">
         <map>
           <entry key="a" value="a1"></entry>
           <entry key="b" value="b1"></entry>
        </map>
     </property>
</bean>

使用util命名空间简化后的写法。可以定义map的细节

1、key-type 定义map的key类型

2、value-type 定义map的value类型

3、map-class 定义使用map接口的哪个实现类,默认是HashMap

<util:map id="myUtilMap" key-type="java.lang.String" value-type="java.lang.String" map- 
class="java.util.TreeMap">
      <entry key="c" value="c1"></entry>
      <entry key="d" value="d1"></entry>
</util:map>

 4.4 util:set

正常定义Set类型Bean需要借助SetFactoryBean

<bean id="mySet" class="org.springframework.beans.factory.config.SetFactoryBean">
   <property name="sourceSet">
      <set>
         <value>a</value>
         <value>b</value>
      </set>
  </property>
</bean>

使用util:set简化后的语法

<util:set id="myUtilSet" value-type="java.lang.String" set-class="java.util.TreeSet">
     <value>c</value>
     <value>c</value>
</util:set>

4.5 util:properties

Properties是从java 1.0就出现的类,是HashTable的子类,存放键值对值。常与物理文件.properties文
件对应。
正常定义一个Properties类型Bean,需要借助PropertiesFactoryBean。
可以直接给定固定值,也可以从外部读取properties文件。在src/main/resources下新建my.properties
文件。
<!-- 使用固定值定义一个properties类型Bean -->
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="a">a1</prop>
            <prop key="b">b1</prop>
        </props>
    </property>
</bean>
<!-- 读取外部properties文件定义一个properties类型Bean -->
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
       <property name="location" value="classpath:my.properties"></property>
</bean>

使用util:properties简化后的代码

<util:properties id="myUtilProperties" value-type="java.lang.String">
      <prop key="c">c1</prop>
      <prop key="d">d1</prop>
</util:properties>

<util:properties id="myUtilProperties2" location="classpath:my.properties">
</util:properties>

4.6 util:property-path

如果想要把某个Bean的属性单独定义成一个Bean,需要借助PropertyPathFactoryBean。 注意:既然是某个Bean的属性要定义成一个Bean,就必须现有这个某个Bean。

<bean id="demo" class="com.tong.pojo.Demo">
     <property name="name" ref="myUtilName"></property>
     <property name="list" ref="myUtilList"></property>
</bean>
<bean id="demo.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"></bean>

 使用util:property-path简化后的代码

<bean id="demo" class="com.tong.pojo.Demo">
       <property name="name" ref="myUtilName"></property>
       <property name="list" ref="myUtilList"></property>
</bean>
<util:property-path id="myPropertyPath" path="demo.age"></util:property-path>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/793433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java 锁详解

死锁有四个条件 1. 互斥性 某个锁单元只能被某个运算单元占用 2. 不可以剥夺 线程获取某个资源, 这个资源不可以被其他资源剥夺, 只能自己释放, 3. 请求并保持 请求别的资源的同时却保持占有某个资源 4. 形成循环链路 一般锁都有互斥性, 读锁没有互斥性. 一般的锁都不…

视觉系统相关的网站

1.视觉系统设计 视觉系统设计网址&#xff1a;http://www.vision-systems-china.com/emag/emag.asp

宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution

宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution 容器参数 docker-compose.yml 的 dns我也设置&#xff0c;按理来说应该可以访问&#xff0c;然而就是不断的按在地上摩擦 web:build: .restart: alwaysports:- "6699:80"dns:- 114.11…

公司内部重要文件如何加密防止泄露?

现如今&#xff0c;是互联网时代&#xff0c;数据安全在互联网时代中的数据安全岌岌可危&#xff0c;企业中&#xff0c;都会拥有终端&#xff0c;终端中每天都要处理文档&#xff0c;文件&#xff0c;表格&#xff0c;产生一系列的数据问题等&#xff0c;这个时候就要先企业中…

Windows OS CMD 常用工具 の 命令合集

# First Of All 每次想要修改环境变量都要按部就班点开系统属性、高级系统设置、环境变量。这种操作实在是太繁琐了&#xff0c;对于我一个懒人来讲实在是 忍无可忍 。如果可以使用 WINR 或 CMD 直接打开系统内的一些工具&#xff0c;是不是就可以节省很多时间&#xff1b;是不…

自己写的程序创建开机自启

1、winr 2、输入shell:startup 3、把需要启动的程序快捷方式放在此文件夹下面即可

最详细的编译paddleOcrGPU C++版本指南(包含遇到坑的解决办法)

前言&#xff1a; 我是之前编译过调用CPU的paddleOcr的C版本&#xff0c;其实CPU版本与GPU版本并无太大不同&#xff0c;只不过是调用库版本的不同&#xff0c;然后原项目中几个相关参数改一下就可以&#xff0c;但是在这个过程中我找不到关于编译paddleOcrGPU C版本的详细教程…

【Docker】Consul的容器服务更新与发现

目录 一、Consul二、什么是服务注册与发现1.2什么是consul1.3consul提供的一些关键特性 二、Consul部署2.1环境配置2.2Consul服务器配置1. 建立 Consul 服务2. 查看集群信息3. 通过 http api 获取集群信息 2.3 registrator服务器配置1. 安装 Gliderlabs/Registrator2. 测试服务…

如何设置Axure中文版 Mac系统下axurerp10怎么设置成中文

有许多小伙伴肯定想知道axure rp 10怎么转换为中文版&#xff0c;接下来就为大家带来最详细的汉化教程&#xff0c;大家可以根据教程一步一步操作&#xff0c;保证可以汉化成功&#xff01; 准备工作 安装好axurerp10 axurerp10汉化包 百度网盘链接: 百度网盘 请输入提取码 …

【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值

最近想用c做一个小游戏&#xff0c;游戏的主要内容是利用键盘控制一个飞机躲避和击落屏幕顶部随机掉落敌方炮弹&#xff0c;飞机被敌方炮弹击中则减掉一条命&#xff0c;飞机也可以发射炮弹反击&#xff0c;每击落一个敌方炮弹&#xff0c;则有相应积分。 游戏的思路就是利用w…

Docker配置阿里云容器镜像加速

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

目录操作在C语言中:一个全面的指南

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

7.26 Qt

用QT制作一个登陆界面 运行代码 login.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //信息调试类&#xff0c;用于输出 #include <QIcon> //图标类头文件 #include <QPushButton&…

更新合集 | 七月功能上新记

点击链接了解详情 七月来临&#xff0c;正式开启 2023 下半年的新征途&#xff01;这个盛夏&#xff0c;腾讯云 CODING 上线了微信扫码注册、微信通知、Go 制品管理等重点能力&#xff0c;为企业及团队研发管理带来更多便利&#xff01;以下是 CODING 新功能速递&#xff0c;快…

一文搞定IP地址

IP编址系列文章&#xff08;上&#xff09; 目录 一&#xff0c;什么是IP地址&#xff1f; 二&#xff0c;IP地址的表示方式 问题&#xff1a;计算机能识别二进制&#xff1f;十进制&#xff1f;十六进制&#xff1f; 三&#xff0c;二进制如何转换为十进制呢&#xff1f; …

如何准备远程开发环境

准备一台有root权限的服务器 创建用于开发的子用户 使用adduser命令创建新用户: sudo adduser newuser为新用户添加sudo权限,编辑sudoers文件: sudo visudo在文件中添加: newuser ALL(ALL:ALL) ALL将新用户添加到docker用户组: sudo usermod -aG docker newuser改权限 ch…

Java 聊天程序案例

单线程版本&#xff1a; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner;//服务端 public class Server {public static void main(String…

HikariCP连接池

HikariCP连接池 HikariCP连接池是高性能的JDBC连接池&#xff0c;官网标注的三大特点&#xff1a;快速、简单、可靠&#xff0c;性能优于其他连接池。 官网详细地说明了HikariCP所做的一些优化&#xff0c;总结如下&#xff1a; 字节码精简&#xff1a;优化代码&#xff0c;直…

领跑人机协同时代!实在智能与EFCIO携手举办AI沙龙,推动企业数字化转型

GPT翻开了AGI&#xff08;通用人工智能&#xff09;领域的新篇章&#xff0c;也开启了各行各业的新时代。毫不夸张地说&#xff0c;进入大模型时代&#xff0c;所有的应用都值得被重写一遍。同时&#xff0c;企业也需要积极采纳新技术和创新模式&#xff0c;以应对竞争压力和不…

MURF2080CT/MURF2080CTR-ASEMI快恢复对管

编辑&#xff1a;ll MURF2080CT/MURF2080CTR-ASEMI快恢复对管 型号&#xff1a;MURF2080CT/MURF2080CTR 品牌&#xff1a;ASEMI 芯片个数&#xff1a;2 芯片尺寸&#xff1a;102MIL*2 封装&#xff1a;TO-220F 恢复时间&#xff1a;50ns 工作温度&#xff1a;-50C~150C…