这篇文章简单汇总一下使用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标签,都类似