1.Bean标签范围配置
scope:指对象的作用范围,取值如下:
取值范围 | 说明 |
---|---|
singleton | 默认值,单例的 |
prototype | 多例的 |
request | WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中 |
session | WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中 |
global session | WEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session |
测试代码:
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl被创建了");
}
@Override
public void save() {
System.out.println("save running...");
}
}
public class SpringTest {
/**
* 测试scope属性
*/
@Test
public void test1() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");
UserDao userDao2 = (UserDao) app.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
}
}
1.当scope的值为singleton时
在applicationContext.xml文件中配置scope
<bean id="userDao" class="com.szly.dao.impl.UserDaoImpl" scope="singleton"></bean>
通过调试,我们发现程序加载配置文件,创建Spring容器时,即执行完第14行代码,创建了Bean对象,而且指向同一个地址。运行结果如下:
因此,当scope的值为singleton时:
Bean的实例化个数:1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
- 对象创建:当应用加载,创建容器时,对象就被创建了
- 对象运行:只要容器在,对象就一直存在
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁
2.当scope的值为prototype时
在applicationContext.xml文件中配置scope
<bean id="userDao" class="com.szly.dao.impl.UserDaoImpl" scope="prototype"></bean>
通过调试,我们发现只有当getBean时才会创建Bean对象,而且每当getBean时就会创建一个新的Bean对象,指向不同的地址,即执行第15、16行代码时。运行结果如下:
因此,当scope的值为prototype时:
Bean的实例化个数:多个
Bean的实例化时机:当调用getBean()放法时实例化Bean
Bean的生命周期:
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,就一直存活着
- 对象销毁:当对象长时间不用时,被Java的垃圾回收器回收
2.Bean生命周期配置
- init-method:指定类中的初始化方法名称
- destroy-method:指定类中销毁方法名称
在上面的UserDaoImpl类中添加以下代码:
public void init() {
System.out.println("初始化方法");
}
public void destroy() {
System.out.println("销毁方法");
}
SpringTest类中添加以下代码:
/**
* 测试Bean声明周期
*/
@Test
public void test2() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
System.out.println(userDao);
// 手动关闭容器
((ClassPathXmlApplicationContext)app).close();
}
运行结果如下:
3.Bean实例化三种方式
- 无参构造方法实例化
- 工厂静态方法实例化
- 工厂实例方法实例化
第一种方法是最常用的,上述1、2使用的均是无参构造方法实例化Bean对象。下面对后两种方法进行测试
1.工厂静态方法实例化Bean对象
首先添加一个工厂类,类中添加一个静态方法,返回一个要创建的对象。
public class StaticFactory {
public static UserDao getUserDao() {
return new UserDaoImpl();
}
}
然后在配置文件applicationContext.xml中配置bean中class属性的值。但此时会使用StaticFactory 类的无参构造实例化Bean对象,所以我们添加一个factory-method,值为工厂类中的一个静态方法getUserDao()。
<bean id="userDao" class="com.szly.factory.StaticFactory" factory-method="getUserDao"></bean>
测试代码:
/**
* 使用工厂静态方法实例化Bean对象
*/
@Test
public void test3() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
System.out.println(userDao);
}
2.工厂实例方法实例化
首先添加一个工厂类,类中添加一个方法,返回一个要创建的对象。
public class DynamicFactory {
public UserDao getUserDao() {
return new UserDaoImpl();
}
}
然后配置applicationContext.xml文件。这时候我们需要配置两个Bean,一个用来获取工厂对象DynamicFactory,一个用来通过工厂对象中的方法来获取我们想要创建的对象。这里有种套娃的感觉。。。
<bean id="factory" class="com.szly.factory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
我们只保留这两个Bean标签,把之前所配置的Bean都给注释了,可以继续使用之前的测试代码来测试。因为此时applicationContext.xml配置文件中只有这一种配置方法。