这篇笔记的实例是在上一篇的基础上的
用于配置对象交由Spring来创建
默认情况下它调用的是类中的无参构造函数, 如果没有无参构造函数则不能创建成功
基本属性
id: Bean实例在Spring容器中的唯一标识
class: Bean的全限定名额
<bean id="userDao" class="com.dao.impl.UserDaoImpl">bean>
scope指对象的作用范围, 取值范围如下
singleton 默认的单例的
prototype 多例的
request 在web项目中, Spring创建一个Bean对象, 将对象存入request域中
session在web项目中, Spring创建一个Bean对象, 将对象存入session域中
global session 在web项目中, 应用在Portlet环境, 如果没有Portlet环境, 那么globalSession相当于session
测试代码
新建一个测试类
public class SpringTest {
@Test
//测试scope属性
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");//参数是id的名字
UserDao userDao2 = (UserDao) app.getBean("userDao");//参数是id的名字
System.out.println(userDao1);
System.out.println(userDao2);
}
}
因为要用到junit进行测试, 需要在maven的pom.xml坐标引入junit坐标, 把以下代码放在
里面
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.9version>
dependency>
设置applicationContext.xml配置文件bean标签内的scope属性值为singleton
<bean id="userDao" class="com.dao.impl.UserDaoImpl" scope="prototype">bean>
测试结果
此时scope范围的属性是singleton, 输出的属性是一样的
把scope属性的值由singleton改成prototype
<bean id="userDao" class="com.dao.impl.UserDaoImpl" scope="prototype">bean>
地址值就不一样了, 在singleton 编程prototype的过程中, 由单个对象变成多个对象了
因为默认的配置情况下它调用的是类中的无参构造函数, 所以在UserDaoImpl复写的无参构造对象
public UserDaoImpl() {
System.out.println("UserDaoImpl创建.....");
}
把scope属性改成singleton进行测试, 测试结果如下
无参构造函数创建一次对象
把scope属性改成prototype进行测试, 测试结果如下
无参构造函数创建两次对象
总结一下:
当scope的取值为singleton时, Bean的实例化个数是1个, Bean的实例化时机是当Spring的核心文件被加载时, 实例化配置Bean的实例
Bean的生命周期
对象创建 : 当应用运行加载, 创建容器时, 对象就被创建
对象运行: 只要容器在, 对象就一定活着
对象销毁: 当应用卸载时, 销毁容器时, 对象就被销毁了
当scope的取值为prototype时, Bean的实例化个数是多个,
Bean的实例化时机: 当调用getBean()方法时实例化Bean
其生命周期如下:
对象创建: 当使用对象时, 创建新的对象实例
对象运行: 只要对象在使用中, 对象就一定活着
对象销毁: 当对象长时间不用, 被Java的垃圾回收器回收了
init-method: 指定类中的初始化方法名称
destroy-method: 指定类中的销毁方法名称
在实现类UserDaoImpl中创建初始化和销毁两个方法
public void init(){
System.out.println("初始化方法......");
}
public void destory(){
System.out.println("销毁方法......");
}
这样在测试类中是无法打印的, 需要在Bean标签中配置init-method和destroy-method方法
<bean id="userDao" class="com.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"></bean>
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");//参数是id的名字
System.out.println(userDao1);
}
那么为什么没有销毁方法呢, 可能是因为还没来的及销毁就被打印了, 需要采取一个关闭按钮, 在测试类中添加这一行代码
((ClassPathXmlApplicationContext) app).close();
无参构造方法实例(上面测试的方法即是)
工厂静态方法实例
工厂实例方法实例
创建一个静态工厂类
package com.factory;
import com.dao.UserDao;
import com.dao.impl.UserDaoImpl;
public class StaticFactory {
public static UserDao getUserDao(){
//返回的是实现对象
return new UserDaoImpl();
}
}
通过配置文件来使用这个静态工厂, 同时也要把无参构造方法给注释调
<bean id="userDao" class="com.factory.StaticFactory" factory-method="getUserDao"></bean>
测试方法的代码不用变
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");//参数是id的名字
System.out.println(userDao1);
}
创建一个工厂实例类, 和工厂静态类的方法基本一致, 只是不要static
public class DynamicFactory {
public UserDao getUserDao(){
//返回的是实现对象
return new UserDaoImpl();
}
}
配置文件
<bean id="factory" class="com.factory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>