Spring5源码分析容器刷新prepareBeanFactory()方法
上一篇:Spring5源码分析-注册配置类
前面已经把配置类的定义已经注册到容器中,还在进行对配置类进行全面分析和处理之前,Spring还要再做一些预处理,比如设置类加载器,设置后置处理器ApplicationContextAwareProcessor,将environment systemProperties systemEnvironment三个对象添加到容器当中,设置Spring框架不需要被自动注入的接口等操作。
源码注释如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 很重要,添加BeanPostProcessor,完成Bean的相关XXXAware接口的注入工作
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 下面的几行代码可以不看 忽略给定的自动装配依赖接口(也就是这些接口对应setter方法自动注入不会被执行)
// 详细文档可以参考博客:https://www.jianshu.com/p/3c7e0608ff1f
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//下面的4行代码,除了BeanFactory是添加的beanFactory,其他(this)都是ApplicationContext对应的子类,
// 比如AnnotationConfigApplicationContext。在进行自动装配的时候需要从beanFactory或者AnnotationConfigApplicationContext中获取对象
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 博客地址:https://www.cnblogs.com/wade-luffy/p/6078446.html
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 往容器中添加environment systemProperties systemEnvironment三个对象
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
查看ApplicationContextAwareProcessor它的postProcessBeforeInitialization方法可以很容易看明白,这个后置处理器是将实现了XXXAware接口类中设置对应的Environment EmbeddedValueResolver ResourceLoader ApplicationEventPublisher MessageSource ApplicationContext对象,可以在自己的实现类中读取相关的值对业务或者框架的行为作出干预。
比如:
@Component@Getter
@Setter
public class IgnoreUser implements EnvironmentAware, ApplicationContextAware {
private Environment environment;
private ApplicationContext applicationContext;
@Autowired
private IgnoreDept dept;
private String name;
private Integer age;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public void show(){
System.out.println(environment.getActiveProfiles());
System.out.println(applicationContext.getBean(IgnoreDept.class));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
三个内置Bean(environment systemProperties systemEnvironment)
既然是内置的Bean,也就是Spring容器中存在的,完全可以使用按照类型的自动注入来获取到对应的Bean
比如上面使用EnvironmentAware让Spring框架通过后置处理调用实现类的setEnvironment()方法来实现,但是还可以换一种写法
public class IgnoreUser implements /*EnvironmentAware, */ApplicationContextAware { @Autowired
private Environment environment;
注释掉implements EnvironmentAware接口,直接使用@Autowired即可
以上是 Spring5源码分析容器刷新prepareBeanFactory()方法 的全部内容, 来源链接: utcz.com/z/510694.html