Spring之ApplicationContextAware接口详解

mac2024-01-26  39

在Spring中,当一个bean实现了ApplicationContextAware接口,这个bean便可以获取到ApplicationContext对象,进而获取应用上下文中的bean。

代码实例

package com.huawei.nlz.springplayground.applicationcontextaware; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringBeanFactory implements ApplicationContextAware { private static ApplicationContext context; /** * 从Spring应用上下文中获取特定类型的bean * * @param c 类型的Class对象 * @param <T> 类型 * @return bean */ public static <T> T getBean(Class<T> c) { return context.getBean(c); } /** * 从Spring应用上下文中获取指定名字的特定类型的bean * * @param name bean名字 * @param c 类型的Class对象 * @param <T> 类型 * @return bean */ public static <T> T getBean(String name, Class<T> c) { return context.getBean(name, c); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } }

这里的SpringBeanFactory被声明为要为之创建单例bean,然后在setApplicationContext回调中,把Spring传过来的ApplicationContext保存到自己内部的静态字段context上,然后将从context上获取bean封装为公共的静态方法开放给其他类调用。

应用场景

一般的应用场景即是上面所示的bean的工厂。以上面的类为例,我们可以通过SpringBeanFactory.getBean("myBean", MyBean.class)来获取bean。这使得在一些无法注入的地方我们也可以获取到bean,比如Util类中,为我们带来极大的便利。

源码分析

最后我们跟踪一下Spring的源码,看看具体是怎么执行的。

我们进入AbstractApplicationContext的refresh方法,

@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); ...

进入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)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); ...

可以看到Spring自动给添加上了一个BeanPostProcessor--ApplicationContextAwareProcessor,

我们看看ApplicationContextAwareProcessor,

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 @Nullable 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((PrivilegedAction<Object>) () -> { 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; } }

ApplicationContextAwareProcessor确实实现了BeanPostProcessor接口,它会判断bean的类型,如果bean是ApplicationContextAware接口,那么就调用这个对象的setApplicationContext方法。

那么BeanPostProcessor是何时调用的呢?

其代码流程如下: AbstractApplicationContext.refresh -> AbstractApplicationContext.finishBeanFactoryInitialization -> ConfigurableListableBeanFactory(DefaultListableBeanFactory).preInstantiateSingletons -> DefaultListableBeanFactory.getBean -> DefaultListableBeanFactory.doGetBean -> DefaultListableBeanFactory.createBean -> AbstractAutowireCapableBeanFactory.doCreateBean -> AbstractAutowireCapableBeanFactory.initializeBean。

我们看下最末尾的AbstractAutowireCapableBeanFactory的initializeBean方法:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 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; }

其中applyBeanPostProcessorsBeforeInitialization会对该bean对象应用所有的beanPostProcessors:

@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } ... public List<BeanPostProcessor> getBeanPostProcessors() { return this.beanPostProcessors; }

 

最新回复(0)