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.触发点