Spring学习记录(八)---Bean的生命周期

时间:2023-02-04 03:18:19

之前说过,在调用下面时,就创建了容器和对象

    ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");

那它又是怎样一步步创建的呢?要销毁怎么销毁?

用一个例子来看

 package com.guigu.spring.Car;

 public class Car {
private String brand; public Car(){
System.out.println("构造函数。。");
}
public String getBrand() {
System.out.println("返回属性。。");
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
System.out.println("设置属性。。");
}
public void init(){
System.out.println("init()。。");
}
public void destroy(){
System.out.println("destroy()。。");
}
}

xml中用init-mehod、 destroy-method表示调用初始化函数和销毁函数

 <bean id="car" class="com.guigu.spring.Car" init-method="init" destroy-method="destroy">
<property name="brand" value="Aodi"></property>
</bean>

main中

   ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Car car=(Car)ctx.getBean("car");
System.out.println(car);
//关闭IOC容器
ctx.close();

输出:

  构造函数。。
  设置属性。。
  init()。。
  car[brand=Aodi]
  destroy()。。

可以看出来,先调用构造函数和设置属性,然后再init()。

 bean后置处理器:检查bean属性的正确性或根据需要修改属性,要实现BeanPostProcessor接口

写一个实现类MyBeanPostProcessor

 package com.guigu.spring.Car;

 import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor { @Override //before
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName);
return bean;
} @Override //after
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessAfterInitialization: "+bean +beanName);
return bean;
}
}

xml中添加此接口

   <bean id="car" class="com.guigu.spring.Car" init-method="init" destroy-method="destroy">
<property name="brand" value="Aodi"></property>
</bean>
4 <!--配置bean后置处理器,不需要配置id-->
5 <bean class="com.guigu.spring.Car"></bean>

再重新运行一次,输出:

   构造函数。。
设置属性。。
postProcessBoforeInitialization: car[brand=Aodi], car

init()。。
postProcessAfterInitialization: car[brand=Aodi], car car[brand=Aodi]
destroy()。。

注意:一个再init之前调用,一个再init之后调用

如何修改属性? 在接口函数中修改

 package com.guigu.spring.Car;

 import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import com.guigu.spring.autowireautowire.Car; public class MyBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName);
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessAfterInitialization: "+bean +beanName);
Car car = (Car) bean; // 获取要修改的bean对象
car.setBrand("Ford"); //修改属性
return bean;
}
}

注意:上面的bean是bean实例本身;beanName指IOC容器配置的bean的名字

这样,就成功修改了属性,输出:

    构造函数。。
设置属性。。
postProcessBoforeInitialization:car[brand=Aodi], car
init()。。
postProcessAfterInitialization: car[brand=Aodi], car car[brand=Ford]
destroy()。。

还可以过滤,因为处理所有bean时,可能对某些进行操作

     @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName); if("car".equals(beanName)){
//过滤的操作
}
return bean;
}

再看一遍bean生命周期

Spring学习记录(八)---Bean的生命周期