这篇文章简单汇总一下使用xml创建Bean对象的时候的一些更加深入的操作内容(一些属性值),因为xml配置方式是比较主流的配置方式。

Bean标签属性

基本例子

首先,一个最简单的例子:

<bean class="pojo.User"/>

应该这样使用他:

ClassPathXmlApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext.xml");

User dzzhyk= (User)ac.getBean(User.class);
System.out.println(dzzhyk);

这里使用的是空构造器,得到的Bean对象user的各项属性是null

User{id='null', username='null', password='null'}

id属性

给bean对象设置id来方便区分,一般都会这么做:

<bean id="user" class="pojo.User"/>

这样我们在获取bean的时候就可以指定id来获取,这样更加准确

ClassPathXmlApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext.xml");

User dzzhyk= (User)ac.getBean("user");	// 使用id获取
System.out.println(dzzhyk);

这里使用的是空构造器,得到的Bean对象user的各项属性是null

User{id='null', username='null', password='null'}

scope属性

scope属性只有两个取值:singleton或者prototype,代表单例/多例

默认是:单例

<bean id="user" class="pojo.User" scope="singleton" />
<bean id="user" class="pojo.User" scope="prototype" />
  • 单例:service、dao、工具类可以使用单例模式,在容器初始化之前(如果不是懒加载)就已经创建了bean,并且整个应用只有一个对象
  • 多例:controller可以使用多例,在使用的时候才创建对象

lazy-init属性

bean是否懒加载,只对scope="singleton"的bean对象起作用。
使其在被使用的时候才被创建,并且保持单例。

<bean id="user" class="pojo.User" lazy-init="true" />

init-method和destroy-method

  • init-method:指定对象创建之后执行的方法
  • destroy-method:指定bean容器销毁的时候执行的方法

创建一个bean对象user,指定其初始化方法和容器销毁时执行方法分别为myInit和myDestroy方法

<bean id="user" class="pojo.User" init-method="myInit" destroy-method="myDestroy">
    <constructor-arg index="0" name="username" type="java.lang.String" value="dzzhyk"/>
    <constructor-arg index="1" name="password" type="java.lang.String" value="123456"/>
</bean>
public void myInit(){
    System.out.println("user初始化...");
}

public void myDestroy(){
    System.out.println("user已销毁...");
}

接下来执行如下代码,查看结果:

ClassPathXmlApplicationContext ac =
        new ClassPathXmlApplicationContext("applicationContext.xml");

User dzzhyk = (User)ac.getBean(User.class);
System.out.println(dzzhyk);

ac.close();     // 关闭容器

这里应该使用ac.close()方法关闭容器,destroy方法已经过时了。

输出结果:

user初始化...
User{id='null', username='dzzhyk', password='123456'}
user已销毁...

factory-bean和factory-method

可以使用工厂方式创建Bean对象

  • 静态工厂

使用静态工厂,首先需要创建一个静态工厂

public class Factory {
    public static User getUser(){
        return new User("dzzhyk", "123456");
    }
}

接下来在配置Bean的时候,直接使用class指向静态类,并且制定静态的工厂方法

<bean id="user" class="Factory" factory-method="getUser"/>
  • 实例工厂

实例工厂就需要先有工厂这个Bean,然后再有user对象bean,并且需要指定其工厂bean和创建方法;首先创建一个实例工厂:

public class Factory {
    public User getUser(){		// 去掉了static
        return new User("dzzhyk", "123456");
    }
}

然后再xml中配置Bean对象:

<bean id="userFactory" class="Factory"/>
<bean id="user" class="pojo.User" factory-bean="userFactory" factory-method="getUser"/>

可以获取对象如下:

User{id='null', username='dzzhyk', password='123456'}

Bean子标签

property标签

刚才的对象都没有属性,使用property标签来赋值

<bean id="user" class="pojo.User">
    <property name="id" value="1"/>
    <property name="username" value="dzzhyk"/>
    <property name="password" value="123456"/>
</bean>

constructor-arg标签

我们不指定bean的构造函数的话,默认使用空构造器,使用constructor-arg标签来指定bean的构造函数

首先,给User类添加一个新的构造函数:

public User(String username, String password) {
    this.username = username;
    this.password = password;
}

然后就可以在创建bean对象的时候指定使用这个构造函数,通过指定各位置的参数类型和值来进行操作。

<bean id="user" class="pojo.User">
    <constructor-arg index="0" name="username" type="java.lang.String" value="dzzhyk"/>
    <constructor-arg index="1" name="password" type="java.lang.String" value="123456"/>
</bean>
  • index:该参数在构造函数中的位置,确定具体的构造器
  • name:该参数的名称
  • type:该参数的类型
  • value:该参数的值(如果是可以直接赋值的参数类型,否则需要使用引用ref)
  • ref:引用另外一个bean对象,填的内容是该bean对象的id

这样最终得到的结果如下:

User{id='null', username='dzzhyk', password='123456'}

constructor-arg指定集合参数

list标签

如果构造器需要传入的参数是一个对象集合,应该怎样使用呢?

假设创建user对象需要传入一个手机号码列表来执行构造函数,手机号列表是一个列表,其元素类型为String,其构造函数如下:

public User(String username, String password, List<String> phones) {
    this.username = username;
    this.password = password;
    this.phones = phones;
}

那么我们在配置xml的时候,如果想要使用constructor-arg来配置,需要这样写:

<bean id="user" class="pojo.User">
    <constructor-arg index="0" name="username" type="java.lang.String" value="dzzhyk"/>
    <constructor-arg index="1" name="password" type="java.lang.String" value="123456"/>
    <constructor-arg index="2" name="phones" type="java.util.List">
        <list value-type="java.lang.String">
            <value>123456789</value>
            <value>987654321</value>
            <value>135248912</value>
        </list>
    </constructor-arg>
</bean>

最终获取到的bean对象如下:

User{id='null', username='dzzhyk', password='123456', phones=[123456789, 123456789, 123456789]}

当然这里也可以使用ref来指定内容为另一个bean

map标签

如果要传递的参数是map类型,其操作也大同小异:

假设创建User对象需要传入一个成绩对照表,其k为科目名称,v为成绩,则有如下构造函数:

public User(String username, String password, Map<String, Integer> grades) {
 this.username = username;
    this.password = password;
    this.grades = grades;
}

那么在配置xml的时候可以进行如下配置:

<bean id="user" class="pojo.User">
    <constructor-arg index="0" name="username" type="java.lang.String" value="dzzhyk"/>
    <constructor-arg index="1" name="password" type="java.lang.String" value="123456"/>
    <constructor-arg index="2" name="grades" type="java.util.Map">
        <map key-type="java.lang.String" value-type="java.lang.Integer">
            <entry key="语文" value="80"/>
            <entry key="数学" value="90"/>
            <entry key="英语" value="100"/>
        </map>
    </constructor-arg>
</bean>

最终获得的bean对象输出如下:

User{id='null', username='dzzhyk', password='123456', grades={语文=80, 数学=90, 英语=100}}

除此之外还有set标签、array标签,都类似