spring 注解开发之生命周期

spring 注解开发之生命周期

  • bean的生命周期:bean创建—初始化----销毁的过程
  • bean的生命周期是由容器管理;
  • 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
  • 构造(对象创建)
    • 单实例:在容器启动的时候创建对象
    • 多实例:在每次获取的时候创建对象

自定义初始化和销毁方法的4种方式

    1. 通过指定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();
        	}
        
    2. 通过让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 {
      	
      }
      
    3. 可以使用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...");
      	}	
      
      }
      
    4. 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();
	}
}

img

/**
	 * 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被实例化。

img

img

img

BeanPostProcessor在Spring底层的使用

    1. 实现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;
      	}	
      
      }
      
      • 实现原理:

    2. 实现BeanValidationPostProcessor接口,做数据校验

    3. InitDestroyAnnotationBeanPostProcessor接口,实现@PostConstruct、@PreDestroy的功能

    4. AutowiredAnnotationBeanPostProcessor接口,实现@Autowired功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值