Spring扩展之五:Aware接口等

ApplicationContextAwareProcessor

1.介绍

ApplicationContextAwareProcessor是一个Spring内部工具,它实现了接口BeanPostProcessor,用于向实现了如下某种Aware接口的bean注入ApplicationContext中相应的属性:

  • EnvironmentAware

  • EmbeddedValueResolverAware

  • ResourceLoaderAware

  • ApplicationEventPublisherAware

  • MessageSourceAware

  • ApplicationContextAware

如果bean实现了以上接口中的某几个,那么这些接口方法调用的先后顺序就是上面接口排列的先后顺序。

EnvironmentAware、ResourceLoaderAware、ApplicationContextAware等

1.介绍

Spring框架预留的关键的接口,Spring容器会自动把Environment、ResourceLoader、ApplicationContext等对象通过set...()方法注入

2.使用

@Component
public final class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    private static Environment environment;

    // 通过set方法注入Environment
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
 
    // 通过set方法注入ApplicationContext
    @Override
    public void setApplicationContext(ApplicationContext contex) throws BeansException {
        this.applicationContext = contex;
    }
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    public static Environment getEnvironment() {
        return environment;
    }
}

3.触发点

ApplicationContextAwareProcessor类下:
private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

 4.顺序图

BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

1.介绍

Spring框架预留的关键的接口,获取当前Bean的名称,获取当前Bean的类装载器和bean工厂。

如果bean实现了以上接口中的某几个,那么这些接口方法调用的先后顺序就是上面排列的先后顺序

2.触发点

 AbstractAutowireCapableBeanFactory类下:

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

@PostConstruct

1.介绍 

标注于需要执行的方法,在bean的初始化阶段,在BeanPostProcessor.postProcessBeforeInitialization之后,InitializingBean.afterPropertiesSet之前

方法不能有任何参数,不能是静态的,返回值必须是void,只会执行一次。

如果想在生成对象时候完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解标注的方法将会在依赖注入完成后被自动调用

执行顺序: 父类静态变量或静态语句块–>子类静态变量或静态语句块->父类实例变量或初始化语句块–>父类构造方法->子类实例变量或初始化语句块->子类构造方法--> @Autowired -> @PostConstruct....-> destroy -> @PreDestroy

2.触发点

 

 

posted @ 2020-11-25 18:06  柒月丶  阅读(437)  评论(0)    收藏  举报