1. Bean 的生命周期:
1). Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.
2). Spring IOC 容器对 Bean 的生命周期进行管理的过程:
<bean id="person" class="com.atguigu.spring.lifecycle.Person"
init-method="init"
destroy-method="destroy">
<property name="name" value="abcd"></property>
</bean>
①. 通过构造器或工厂方法创建 Bean 实例:调用构造器
②. 为 Bean 的属性设置值和对其他 Bean 的引用:调用 setter
③. 将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
④. 调用 Bean 的初始化方法:init-method
⑤. 将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法
⑥. Bean 可以使用了
⑦. 当容器关闭时, 调用 Bean 的销毁方法:destroy-method
3). Bean 的后置处理器(了解):Spring
提供的特殊的 Bean
①. Bean 后置处理器允许在调用初始化方法(即:bean 节点 init-method 属性对应的方法的前后)前后对 Bean 进行额外的处理.
②. Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
③. 对Bean 后置处理器而言, 需要实现 BeanPostProcessor 接口
public class PersonPostProcessor implements
BeanPostProcessor {
/**
* arg0:IOC 容器中 bean 的实例
* arg1:IOC 容器中该 bean 的名字
*/
@Override
public Object
postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
if(arg0 instanceof Person){
System.out.println("postProcessAfterInitialization");
Person person = (Person) arg0;
String name = person.getName();
if(!name.equals("AAAA")){
System.out.println("name 值必须为 AAAA!");
person.setName("AAAA");
}
}
return arg0;
}
@Override
public Object
postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("postProcessBeforeInitialization");
return arg0;
}
}
④. Bean 后置处理器需要在 IOC 容器中进行配置,但不需要指定 id 属性, Spring IOC 容器会自动的识别这是个 Bean 后置处理器,自动的使用它。
<bean class="com.atguigu.spring.lifecycle.PersonPostProcessor"/>
2. 使用工厂方法配置 bean(了解)
1). 使用静态工厂方法来配置 bean
①. 静态工厂方法:直接调用某一个类的静态方法即可返回对应类的一个实例
public class StaticCarFactory {
private static Map<String, Car> cars = new HashMap<String, Car>();
static{
cars.put("ford", new Car("ford", "ChangAn", 200000, 200));
cars.put("mazda", new Car("Mazda", "ChangAn", 210000, 210));
}
public static Car get(String brand){
return cars.get(brand);
}
}
②. 配置:
<bean id="car3" class="com.atguigu.spring.factory.StaticCarFactory"
factory-method="get">
<constructor-arg
value="ford"></constructor-arg>
</bean>
注意:
I. class 指向的是静态工厂类;
II. factory-method 配置的是静态工厂方法中的方法;
III. 若静态方法需要传入参数,则使用 <constructor-arg value="ford"></constructor-arg> 方式传入参数
2). 使用实例工厂方法来配置 bean
public class InstanceCarFactory {
private Map<String, Car> cars = new HashMap<String, Car>();
public InstanceCarFactory() {
cars.put("ford", new Car("ford", "ChangAn", 200000, 200));
cars.put("mazda", new Car("Mazda", "ChangAn", 210000, 210));
}
public Car get(String brand){
return cars.get(brand);
}
}
<!-- 1. 配置实例工厂本身的 bean -->
<bean id="carFactory" class="com.atguigu.spring.factory.InstanceCarFactory"></bean>
<!-- 2.增加实例工厂方法配置 bean -->
<bean id="car4" factory-bean="carFactory" factory-method="get">
<constructor-arg value="mazda"></constructor-arg>
</bean>
3. 通过 FactoryBean 来配置 Bean 的实例(关注):
1). 实现 FactoryBean 接口:
public class CarFactoryBean implements FactoryBean<Car> {
//返回的 Bean 的实例
@Override
public Car getObject() throws Exception {
return new Car("BMW", "HUACHEN", 300000, 300);
}
//返回的 Bean 的类型
@Override
public Class<?> getObjectType() {
return Car.class;
}
//返回的 Bean 是否为单例
@Override
public boolean isSingleton() {
return true;
}
}
2). 在 IOC 容器中配置 Bean:class 属性指向 FactoryBean 接口的实现类,实际返回的是 FactoryBean 的 getObject() 方法的 Bean
<bean id="car5" class="com.atguigu.spring.factorybean.CarFactoryBean"></bean>
3). 使用
Car car = (Car) ctx.getBean("car5");