spring 注解开发之生命周期
- bean的生命周期:bean创建—初始化----销毁的过程
- bean的生命周期是由容器管理;
- 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
- 构造(对象创建)
- 单实例:在容器启动的时候创建对象
- 多实例:在每次获取的时候创建对象
自定义初始化和销毁方法的4种方式
-
-
通过指定init-method和destroy-method;
-
使用xml方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 包扫描、只要标注了@Controller、@Service、@Repository,@Component --> <!-- <context:component-scan base-package="com.atguigu" ></context:component-scan> --> <bean id="person" class="com.atguigu.bean.Car" init-method="init" destroy-method="destroy"> </bean> </beans>
public class Car { public Car(){ System.out.println("car constructor..."); } public void init(){ System.out.println("car ... init..."); } public void destroy(){ System.out.println("car ... detory..."); } }
-
使用注解方式
@Configuration public class MainConfigOfLifeCycle { //@Scope("prototype") @Bean(initMethod="init",destroyMethod="detory") public Car car(){ return new Car(); }
@Test public void test01(){ //1、创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器创建完成..."); //applicationContext.getBean("car"); //关闭容器 applicationContext.close(); }
-
-
通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑);
@Component public class Cat implements InitializingBean,DisposableBean { public Cat(){ System.out.println("cat constructor..."); } @Override public void destroy() throws Exception { // TODO Auto-generated method stub System.out.println("cat...destroy..."); } //在bean创建完对象赋值完后调用 @Override public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println("cat...afterPropertiesSet..."); } }
@ComponentScan("com.atguigu.bean") @Configuration public class MainConfigOfLifeCycle { }
-
可以使用JSR250
- @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
- @PreDestroy:在容器销毁bean之前通知我们进行清理工作
@Component public class Dog { public Dog(){ System.out.println("dog constructor..."); } //对象创建并赋值之后调用 @PostConstruct public void init(){ System.out.println("Dog....@PostConstruct..."); } //容器移除对象之前 @PreDestroy public void detory(){ System.out.println("Dog....@PreDestroy..."); } }
-
BeanPostProcessor【interface】:bean的后置处理器;
- 在bean初始化前后进行一些处理工作;
- postProcessBeforeInitialization:在初始化之前工作
- postProcessAfterInitialization:在初始化之后工作
/** * 后置处理器:初始化前后进行处理工作 * 将后置处理器加入到容器中 */ @Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean); return bean; } }
-
BeanPostProcessor原理
- 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization
- 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
- BeanPostProcessor原理
- populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
- initializeBean
- applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
- invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
- applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
通过debug进行查看源码:
public class IOCTest_LifeCycle {
@Test
public void test01(){
//1、创建ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成...");
//applicationContext.getBean("car");
//关闭容器
applicationContext.close();
}
}
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
refresh()的定义信息
Load or refresh the persistent representation of the configuration,
which might an XML file, properties file, or relational database schema.As this is a startup method, it should destroy already created singletons if it fails, to avoid dangling resources. In other words, after invocation of that method, either all or no singletons at all should be instantiated. @throws BeansException if the bean factory could not be initialized @throws IllegalStateException if already initialized and multiple refresh attempts are not supported
我自己的翻译,如果不对请大家改正:
-
加载或刷新持久化配置,这个配置可能是xml、properties或是相关的数据库schema
因为这是一个启动方法,为了避免吊着资源,如果它失败的话应该销毁已经创建好的单实例,换句话说,在调用该方法之后,要么全部要么根本没有单实例bean被实例化。
BeanPostProcessor在Spring底层的使用
-
-
实现ApplicationContextAware接口,将applicationContext容器注入进来
@Component public class Dog implements ApplicationContextAware { //@Autowired private ApplicationContext applicationContext; public Dog(){ System.out.println("dog constructor..."); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } }
-
实现原理:
-
-
实现BeanValidationPostProcessor接口,做数据校验
-
InitDestroyAnnotationBeanPostProcessor接口,实现@PostConstruct、@PreDestroy的功能
-
AutowiredAnnotationBeanPostProcessor接口,实现@Autowired功能
-