Spring注解(六) Bean生命周期

171 阅读2分钟

方法1 手动编写方法

手动写bean的构造器, 初始方法, 销毁方法

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 destroy...");
   }
}
  • 注入
 @Configuration
public class CarConfig {

    @Bean(initMethod = "init", destroyMethod = "destroy")
    public Car car() {
        return new Car();
    }
}
  • 测试
    @Test
    void testLifeTime() {
        AnnotationConfigApplicationContext ioc = getIoc(CarConfig.class);
        System.out.println("容器创建完成....");
        String[] beans = ioc.getBeanDefinitionNames();
        for (String bean : beans) {
            System.out.println(bean);
        }
        // 关闭容器
        ioc.close();
    }
  • 结果 单例情况下
Car Constructor...
Car Init...
容器创建完成....
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
carConfig
car
Car destroy...

备注: 多实例容器不会调用销毁方法, 多实例方法时.

方法2 实现接口

public class Car2 implements InitializingBean, DisposableBean {
    // 销毁
    @Override
    public void destroy() throws Exception {
        
    }
    //初始化
    @Override
    public void afterPropertiesSet() throws Exception {
        
    }
}

方法3 JSR250注解

  1. @PostConstruct 创建完成并且属性赋值完成
  2. @PreDestroy Bean在容器移除之前
public class Dog {
    public Dog() {
        System.out.println("dog constructor");
    }
    @PostConstruct
    public void init() {
        System.out.println("dog postconstruct");
    }
    @PreDestroy
    public void destroy() {
        System.out.println("dog PreDestroy...");
    }
}

方法4 实现BeanPostProcessor接口

后置处理器 初始化前后进行运作

  1. MyBeanPostProcessor 实现类里的方法, 会在每个bean被注入的期间调用, 强调是所有bean
  2. 是初始化前后不是实例化(调用默认构造方法)
  • 要求MyBeanPostProcessor要被注入容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 后置处理器 初始化前后进行运作
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
     // 初始化之前调用
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "postProcessBeforeInitialization");
        return bean;
    }
	// 初始化之后调用
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "postProcessAfterInitialization");
        return bean;
    }
}

注意: 执行过程中会遍历BeanPostProcessor 挨个执行beforeInitailiaztion, 若果有一个返回null就不执行了(以后再看)

普通类获取IOC容器

实现ApplicationContextAware接口

@Configuration
public class Apple implements ApplicationContextAware {

    public ApplicationContext ioc;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ioc = applicationContext;
        System.out.println(ioc.getApplicationName());
    }
}
  • 测试
    @Test
    void testApplicationContextAware() {
        AnnotationConfigApplicationContext ioc = getIoc(Apple.class);
        String[] beans = ioc.getBeanDefinitionNames();
        for (String bean : beans) {
            System.out.println(bean);
        }
        Apple apple = ioc.getBean(Apple.class);
        System.out.println(apple.ioc.getId());
    }
  • 小结 核心就是类似于回调的方式, 在bean的生命周期中触发某些postprocessor BeanValidationProcessor, 数据校验的接口 InitDestroyAnnotationProcessor 管理@PostConstrut的接口 AutowiredAnnotationBeanProcessor 管理自动注入@Autowired注解的接口