一、ApplicationContextAware使用
作用:在web应用程序里面拿到spring容器ApplictionContext.
原理:spring容器创建完bean后,会通过检测该bean是否实现了ApplicationContextAware接口,如果实现了,会调用setApplicationContext发放,将容器本身返回给应用程序
源码实现:
class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; private final StringValueResolver embeddedValueResolver; /** * Create a new ApplicationContextAwareProcessor for the given context. */ public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory()); } @Override public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareInterfaces(bean); return null; } }, acc); } else { invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { 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); } } } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } }
使用范例:
@Component public class BeanTool implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext context) throws BeansException { if(applicationContext == null) { applicationContext = context; } } public static Object getBean(String name) { return applicationContext.getBean(name); } public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }
二、BeanPostProcessor与InitializingBean比较与使用
/** * BeanPostProcessor 为每个bean实例化时提供个性化的修改,做些包装等 */ package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; public interface BeanPostProcessor { /** * 在bean实例化前调用*/ Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * 在bean实例化后调用,如果bean实现了InitializingBean,则在执行完* 该接口的afterPropertiesSet方法后调用 ,如果实现了init-method则 * 在执行完init-method后调用*/ Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
package org.springframework.beans.factory; /** /* *InitializingBean 为实现该接口的bean提供默认的初始化方法 *也可以在xml配置bean的使用init-method来实现初始化方法 */*/ public interface InitializingBean { void afterPropertiesSet() throws Exception; }
InitializingBean和BeanPostProcessor的执行顺序:构造方法-->BeanPostProcessor-->InitializingBean-->bean中的初始化方法
bean的最终初始化是由AbstractAutowireCapableBeanFactory的initializeBean方法来完成的,下面就不一一贴出来了