ApplicationContextAware实战+源码分析
1.ApplicationContextAware简介
首先我们了解一下ApplicationContextAware的作用,Aware本义就是"自动的",顾名思义spring给我们自动做了些事情。spring有很多以Aware结尾的类,有EnvironmentAware、ApplicationContextAware、MessageSourceAware等
2.源码分析
我们知道spring容器启动要调用 AbstractApplicationContext 中的 refresh() 方法 (Spring源码分析请查看 xxxxx)。通过调试我们发现在refresh()方法的第11步【finishBeanFactoryInitialization():初始化所有剩下的单实例bean】 会调用到ApplicationContextAware接口。
接下来,我们来一步步分析是怎么调用到ApplicationContextAware接口的。
- finishBeanFactoryInitialization(beanFactory)
- beanFactory.preInstantiateSingletons()
- this.getBean(beanName)
- this.doGetBean(name, (Class)null,(Object[])null,false)
- this.getSingleton(()->{xxx})
- singletonFactory.getObject()
- this.createBean(beanName, mbd,args)
- this.doCreateBean(beanName, mbdToUse, args)
- this.initializeBean(beanName, exposedObject, mbd)
- this.applyBeanPostProcessorsBeforeInitialization(bean, beanName)
- processor.postProcessBeforeInitialization(result,
beanName)- invokeAwareInterfaces(bean)
- invokeAwareInterfaces方法中有一个判断
if (bean instanceof ApplicationContextAware) {
bean.setApplicationContext (this.applicationContext);
}
所以我们可以通过实现ApplicationContextAware的setApplicationContext方法做我们想做的事
finishBeanFactoryInitialization()最后一步会将创建的Bean添加到DefaultSingletonBeanRegistry的缓存singletonObjects中(即我们所说的spring一级缓存)。
Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
3.ApplicationContextAware 应用实战
1)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static Logger logger = LoggerFactory.getLogger(ApplicationContextAware.class);
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法。设置上下文环境
*
* @param applicationContext
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
public static boolean isProfileActived() {
return false;
}
}
使用方法
//通过Util获取到你想得到的Bean
SpringContextUtil.getBean("beanName");
- 待续…