Spring学习笔记:XML装配Bean

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/sinat_38393872/article/details/95073043

这片文章是对自己学习的总结,学习材料是Java EE互联网轻量级框架整合开发 SSM框架(Spring MVC + Spring + Mybatis)和Redis实现。作者是杨开振,周吉文,梁华辉和谭茂华。

本文可单独查看,也可以接着这篇文章看。

bean是一个类,不是像String,Arraylist这样被定义好的具体的类。Bean里存放着一个类的实例描述信息(不是实例),用户可以通过这个Bean所属容器中的getBean方法得到类的实例。

说到这里,bean实际上就是一个类,是放在Spring IoC这个容器中的类。我们要用简单的描述信息从Spring IoC中得到对象,这个动作就是装配bean(这部分的细节以及什么是Spring Ioc容器可以看这篇文章https://blog.csdn.net/sinat_38393872/article/details/95076976


基于XML的装配

XML装配的大框架如下所示

<?xml version = '1.0' encoding = 'UTF-8' ?>
<beans xmlns = "http://wwww.springframework.org/schema/beans"
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
    xsi:shemaLocation = "http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <bean id="class1" class="com.ssm.chapter9.pojo.Role">
        <!元素配置信息>
    </bean>
    <bean id="class2" class="com.ssm.chapter9.pojo.Role">
        <!元素配置信息>
    </bean>
</beans>

第一个标签xml和第二个beans中的属性我们不用在意,它是标注着这个xml中是装配Bean的,这部分的代码可在Spring官方文档(https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/core.html#spring-core)的Configuration metadata章节中找到。关注bean标签就好。

前面提到bean其实就是一个类,一个XML文件中可以同时添加多个类。bean中id是标识这个类的属性,它不一定是类名,我们只是用它标识这个类,相当于取一个别的名字。id并不是必须的,如果我们没有声明id,那系统会自动为其添加编号"全限定名#编号",编号从0开始。比如在com.ssm.chapter9.pojo.Role这个包下我们第一次添加一个没有声明id的类,那么系统就自动认为这个类的id是"com.ssm.chapter9.pojo.Role#0",这个路径下第二个没有声明编号的类的默认id就是"com.ssm.chapter9.pojo.Role#1",以此类推。

class是类的全限定名。

下面开始说xml装配Bean的各种方式。

                                                                                                               分割线                                                                                                         

  • 通过构造器装配Bean

如果一个类中有构造器,那就可以用该方法装配Bean。比如一个类的代码如下

package com.ssm.chapter9.pojo;
public class Role{
    private int id;
    private String roleName;
    public Role(int id, String roleName){
        this.id = id;
        this.roleName = roleName;
    }

那么xml中就可以constructor-arg这个标签来为构造器注入参数,使用构造器获取实例。下面的代码的代码是装配Role类。

<!--该xml名为xml.xml-->
<bean id="role" class="com.ssm.chapter9.pojo.Role">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="总经理"/>
</bean>

index表示第几个参数。value表示参数的值,如果参数的类型是引用的话,value要换成ref。

这样在java项目中的其它部分就可以使用下面代码获得Role.id=1,Role.roleName="总经理"的Role实例

ApplicationContext ac = new ClassPathXmlApplicationContext("xml.xml");
Role role = (Role) ac.getBean("role");

                                                                                                               分割线                                                                                                         

  • 通过setter注入

只要Bean类定义了符合Java Bean规范所定义的setter方法即可使用。Java Bean规范的setter方法是指,如果类中的一个变量的名字是variable,然后类中定义了setVariable(value)方法,其中方法名称必须是set+变量名首字母大写的形式,如果没有对应的setter方法,那注入会失败。

比如下面的Role类

package com.ssm.chapter9.pojo;
public class Role{
    private int id;
    private String roleName;
    private int age;
    public setId(int id){
        this.id = id;
    }
    public setRoleName(String roleName){
        this.roleName = roleName;
    }    
}

这个类就可以用下面的代码装配Bean

<!--该xml名为xml.xml-->
<bean id="role" class="com.ssm.chapter9.pojo.Role">
    <property name="id" value="1">
    <property name="roleName" value="总经理">
</bean>

这个能得到Role.id=1,Role.roleName="总经理"的Role实例,因为age没有setter方法,所以不能对age赋值。

利用setter方法装配Bean细节比较多,比如成员变量的类型是引用,链表等,xml使用的标签也不一样,下面就详细介绍。

                                                                                                               分割线                                                                                                         

  • 基本类型成员变量和引用型成员变量

基本类型的成员变量的声明就是如下所示

<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <property name = "id" value = "1"/>
    <property name = "roleName" value = "1"/>
</bean>

property name属性就是变量名称,value就是变量的值。

引用型成员变量如下所示

<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <property name = "id" value = "1"/>
    <property name = "roleName" value = "1"/>
</bean>
<bean id="class2" class="com.ssm.chapter9.pojo.Role2">
    <property name = "class1" ref = "class1">
<bean/>

类class2中的唯一一个成员是class1,它的类型是Role1。这个成员就是一个类,它的值是参考id为class1的类。

                                                                                                               分割线                                                                                                         

  • 集合

这部分Spring官方文档点击这里查看

集合Set,Map,List等装配方式不同,现在开始讲解他们的装配方式。先说Set以及继承Set的类的装配方式

<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <property name = "set">
        <set>
            <value>value1</value>
            <ref bean="class1"/>
        </set>
    </property>
</bean>

第一个value的类型是普通类型,第二个class1是引用类型,两种类型写法不太一样。

 

现在讲Map及其子类的装配方式

<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key-ref ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
</bean>

Map普通类型是通过entry key value标签赋值,引用类型是通过entry key-ref value-ref赋值

 

现在讲list及其子类装配方式

<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
</bean>

普通类型用value标签赋值,引用类型用ref bean标签赋值。

                                                                                                               分割线                                                                                                         

  • Properties的装配方式
<bean id="class1" class="com.ssm.chapter9.pojo.Role1">
    <props>
        <prop key = "prop1">value1</prop>
        <prop key = "prop2">value2</prop>
    </prop>
</bean>

Properties是通过prop key设键,value设值。

我们定义好一个描述信息XML后,在Java程序中得到对象就如下所示

//下面的内核是通过反射得到的对象
JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");
/*下面是得到果汁对象的代码,因为是通过getBean得到的对象(实际上是反射得到对象),
所以类型是Object,需要将类型强制转换一下。其中对奶茶的描述信息也被记录在对象juiceMaker之中。
这里描述和得到对象的代码是分离的,以后想要其它的奶茶,只需要对XML进行就该就好了*/
String juice - juiceMaker.makeJuice();

 

                                                                                                               分割线                                                                                                         

xml装配Bean还可以使用命名空间装配,这个就在写法上有一些简便。使用命名空间就必须引入命名空间代码。

  • 引入c命名空间

c命名空间要在开头就引入,就是在原有的配置语句上加上第3行代码。引入c命名空间的代码可以在c命名空间里找到。

<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

c命名空间就相当于构造器注入,它写法上比构造器注入简单。

1、可以使用参数索引来对构造器参数赋值

<bean id="class1" class="com.ssm.chapter9.pojo.Role" c:_0="1" c:_1="总经理">

上面的写法就直接定义了Role类构造器第一个参数是1,第二个参数是总经理。这种方法只适合只拥有一个构造器的类,多个构造器的就会出错。而且如果参数类型是引用的话,要写成下面的形式

<bean id="class1" class="com.ssm.chapter9.pojo.Role" c:_0-ref="class1" c:_1-ref="class2">

如果参数类型是集合数组等那又是其它写法,在介绍完util命名空间就知道怎么写了。

 

2、使用参数名称对构造器参数赋值

<bean id="class1" class="com.ssm.chapter9.pojo.Role" c:id="1" c:roleName="总经理">

同样的,如果参数类型是引用,要在后面加上-ref,如下所示

<bean id="class1" class="com.ssm.chapter9.pojo.Role" c:id-ref="class1" c:roleName-ref="class2">

如果参数类型是集合数组等在介绍完util命名空间就知道怎么写了。

 

  • 引入p命名空间

p命名空间要在开头就引入,就是在原有的配置语句上加上第3行代码。引入p命名空间的代码可以在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">

p命名空间就相当于setter方法注入,写法上也比一般的setter方法简单。p命名空间只能通过成员变量的名称来赋值,不能通过索引进行赋值。具体写法如下所示

<bean id="class1" class="com.ssm.chapter9.pojo.Role" p:id="1" p:roleName="总经理">

如果成员变量类型是引用,那要在后面加上-ref,如下所示

<bean id="class1" class="com.ssm.chapter9.pojo.Role" p:id-ref="class1" p:roleName-ref="class2">

 

如果参数类型是集合数组等在介绍完util命名空间就知道怎么写了

  • 引入util命名空间

p命名空间和c命名空间中若想对类型是集合的赋值,那么就要引用util命名空间。在原有配置语句上加上第三行,第七行和第八行。

<?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        
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util     
    https://www.springframework.org/schema/util/spring-util.xsd">

命名空间对集合类型赋值,要在bean标签之外定义util命名空间的对象。比如参数类型是list,该list里有两个元素,类型是引用,定义该util对象代码如下

<util:list id="list1">
    <ref bean="role1">
    <ref bean="role2">
</util:list>

代码如xml装配集合类型一样,只是在标签前面和结尾加上命名空间util:。

定义好util命名空间的对象后,p和c命名空间就可以将集合类型看成引用类型对变量进行赋值,具体代码如下。

<bean id="class1" class="com.ssm.chapter9.pojo.Role" c:_0-ref="list1" c:_1-ref="map1">

猜你喜欢

转载自blog.csdn.net/sinat_38393872/article/details/95073043