在工作中,我们可能会使用到像下面这样的代码,用于从spring容器中获取我们想要的bean,那么,为什么这样就可以从spring容器中获的到呢?这篇文章就沿着主线梳理一下。
为了视线清晰,本篇在贴源码时时省略许多不相关的代码
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextHolder.applicationContext = applicationContext;
}
/**
* 获取spring的bean
*/
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
/**
* 获取spring的bean
*/
public static <T> T getBean(String beanName, Class<T> requiredType) {
return applicationContext.getBean(beanName, requiredType);
}
/**
* 获取spring的bean
*/
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
public interface ApplicationContextAware extends Aware {
/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
ApplicationContextAware继承了Aware这个顶级接口,而Aware这个接口里面其实啥也没有,就是起着一个标识的作用。ApplicationContextAware中只有一个方法,正如方法注释所言,在对象运行时设置ApplicationContext,通常被用来初始化对象。
下面这个方法是spring在容器准备阶段执行的,今天,我们也从这里开始梳理。
AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 省略部分代码
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 省略部分代码
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 省略部分代码
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 省略部分代码
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
首先沿着
prepareBeanFactory(beanFactory);
代码进去
AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 省略部分代码
}
这段代码里,添加了一个后置处理器ApplicationContextAwareProcessor,这个很关键,后面会提到。
new ApplicationContextAwareProcessor(this)
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
通过构造方法,给ApplicationContextAwareProcessor这个后置处理器的applicationContext进行赋值,通过ConfigurableApplicationContext的继承关系可以看到,ConfigurableApplicationContext继承了ApplicationContext,也属于bean工厂。

然后回到开头的代码,这次沿着
finishBeanFactoryInitialization(beanFactory);
这块代码进入,这个方法看名字就知道是创建实例的。我们自己定义的ApplicationContextHolder交给了spring去管理,自然也会被创建。
AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 省略部分代码。。。
// 省略部分代码。。。
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 省略部分代码。。。
return exposedObject;
}
从这个方法里面可以看到,先是使用createBeanInstance(beanName, mbd, args)创建出了一个实例,然后通过 populateBean(beanName, mbd, instanceWrapper);填充属性,再然后通过initializeBean(beanName, exposedObject, mbd);执行初始化bean,这个也是我们此次要跟进的方法。
AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
这个方法里面就是执行后置处理器的postProcessBeforeInitialization方法,初始化方法,和后置处理器的postProcessAfterInitialization方法。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
其中就有我们开头上面提到的后置处理器ApplicationContextAwareProcessor
ApplicationContextAwareProcessor#postProcessBeforeInitialization
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
// 省略部分代码。。。
if (acc != null) {
// 省略部分代码。。。
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
ApplicationContextAwareProcessor#invokeAwareInterfaces
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);
}
}
}
由于ApplicationContextHolder实现了ApplicationContextAware接口,所以最后一行代码肯定会执行,也就是说会执行ApplicationContextHolder的setApplicationContext方法,这里的this就是ApplicationContextAwareProcessor,它的applicationContext属性值就是上面提到的,通过它自己的构造方法完成对applicationContext属性的赋值的。而我们ApplicationContextHolder中的setApplicationContext就是把这个applicationContext赋值给了我们自己的一个属性,所以,我们就可以通过ApplicationContextHolder来从spring的容器中获取指定的bean了。
spring中还有很多像ApplicationContextAware这样的接口,感兴趣的可以研究研究~~~