Spring5 源码分析-容器刷新-prepareBeanFactory()方法

上一篇:Spring5源码分析-注册配置类html

前面已经把配置类的定义已经注册到容器中,还在进行对配置类进行全面分析和处理以前,Spring还要再作一些预处理,好比设置类加载器,设置后置处理器ApplicationContextAwareProcessor,将environment  systemProperties systemEnvironment三个对象添加到容器当中,设置Spring框架不须要被自动注入的接口等操做。java

源码注释以下:app

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对象,能够在本身的实现类中读取相关的值对业务或者框架的行为做出干预。ide

好比:源码分析

@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)post

既然是内置的Bean,也就是Spring容器中存在的,彻底能够使用按照类型的自动注入来获取到对应的Beanthis

好比上面使用EnvironmentAware让Spring框架经过后置处理调用实现类的setEnvironment()方法来实现,可是还能够换一种写法spa

public class IgnoreUser implements /*EnvironmentAware, */ApplicationContextAware {
	@Autowired
	private Environment environment;

注释掉implements EnvironmentAware接口,直接使用@Autowired便可.net

相关文章
相关标签/搜索