Spring学习笔记--高级特性之后置处理器(SpringBean的生命周期)

Spring学习笔记–高级特性之后置处理器

Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和BeanFactoryPostProcessor,两者在使⽤上是有所区别的。
工厂初始化(BeanFactory)—> Bean对象
在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情
在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处理做⼀些事情
注意:对象不⼀定是springbean,⽽springbean⼀定是个对象SpringBean的⽣命周期

SpringBean的生命周期

Spring学习笔记--高级特性之后置处理器(SpringBean的生命周期)_第1张图片

  1. 根据配置情况调用Bean构造方法或者工厂方法实例化Bean
  2. 利用依赖注入完成Bean中所有属性值的注入
  3. 如果Bean实现了BeanNameAware接口,则Spring调用Bean的setBeanName()方法传入当前Bean的id值。
  4. 如果Bean实现了BeanFactoryAware接口,则Spring调用setBeanFactory()传入当前工厂实例的引用。
  5. 如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicationContext()方法传入当前ApplicationContext实例的引用。
  6. 如果BeanPostProcessor和Bean关联,则Spring将调用该接口的预初始化方法。postProcessBeforeInitialzation()对Bean进行加工操作,此处非常重要,Spring的AOP就是利用它来实现的。
  7. 如果Bean实现了InitializingBean接口,则Spring将调用afterPropertiesSet()方法。
  8. 如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法。
  9. 如果BeanPostProcessor和Bean关联,则Spring将调用该接口的初始化方法postProcessAfterInitialization()。此时Bean已经可以被应用系统使用了。
  10. 如果在中指定了该Bean的作用范围为scope=“singleton”,则将该Bean放入SpringIoc的缓存池中,将触发Spring对该Bean生命周期管理,如果在中指定了该Bean的作用范围scope=“prototype”,则将交给JVM对Bean的生命周期就行管理。
  11. 如果Bean实现了DisposableBean接口,则Spring会调用destory()方法将Spring中的Bean进行销毁,如果在配置文件中通过destory-method属性制定了Bean的销毁方法,则Spring将调用该方法对Bean进行销毁。
    注意:Spring为Bean提供了细致全面的生命周期过程,通过实现特定的接口或者的属性设置,都可以对 Bean 的⽣命周期过程产⽣影响。虽然可以随意配置 的属性,但是建议不要过多地使⽤ Bean 实现接⼝,因为这样会导致代码和 Spring 的聚合过于紧密
    在实例化Bean之前,需要先去将Bean解析成BeanDefinition
    Spring学习笔记--高级特性之后置处理器(SpringBean的生命周期)_第2张图片
public class Result implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean, DisposableBean {
     

    private String status;
    private String message;

    public String getStatus() {
     
        return status;
    }

    public void setStatus(String status) {
     
        this.status = status;
    }

    public String getMessage() {
     
        return message;
    }

    public void setMessage(String message) {
     
        this.message = message;
    }

    @Override
    public String toString() {
     
        return "Result{" +
                "status='" + status + '\'' +
                ", message='" + message + '\'' +
                '}';
    }

    @Override
    public void setBeanName(String name) {
     
        System.out.println("注册我成为bean时定义的id:" + name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
     
        System.out.println("管理我的beanfactory为:" + beanFactory);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
     
        System.out.println("高级容器接口ApplicationContext:" + applicationContext);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
     
        System.out.println("afterPropertiesSet......");
    }


    public void initMethod() {
     
        System.out.println("init-method....");
    }

    @PostConstruct
    public void postCoustrcut() {
     
        System.out.println("postCoustrcut");
    }


    @PreDestroy
    public void PreDestroy(){
     
        System.out.println("PreDestroy...");
    }

    @Override
    public void destroy() throws Exception {
     
        System.out.println("destroy.....");
    }
}

其中initMethod方法和@PostConstruct修饰的postConstruct方法都是在bean创建时

BeanPostProcessor

创建BeanPostProcessor实现类

拦截实例化之后的对象,实例化并且属性注入了。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
     

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     
        if("lazyResult".equalsIgnoreCase(beanName)) {
     
            System.out.println("MyBeanPostProcessor  before方法拦截处理lazyResult");
        }

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
     
        if("lazyResult".equalsIgnoreCase(beanName)) {
     
            System.out.println("MyBeanPostProcessor  after方法拦截处理lazyResult");
        }
        return bean;
    }
}

该接⼝提供了两个⽅法,分别在Bean的初始化⽅法前和初始化⽅法后执⾏,具体这个初始化⽅法指的是
什么⽅法,类似我们在定义bean时,定义了init-method所指定的⽅法定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每
个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。

BeanFactoryPostProcessor

BeanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,典型应⽤:PropertyPlaceholderConfigurer

@FunctionalInterface
public interface BeanFactoryPostProcessor {
     
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

此接⼝只提供了⼀个⽅法,⽅法参数为ConfigurableListableBeanFactory,该参数类型定义了⼀些⽅法
Spring学习笔记--高级特性之后置处理器(SpringBean的生命周期)_第3张图片
其中有个⽅法名为getBeanDefinition的⽅法,我们可以根据此⽅法,找到我们定义bean 的BeanDefinition对象。然后我们可以对定义的属性进⾏修改,以下是BeanDefinition中的⽅法

你可能感兴趣的:(spring,java)