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

相關文章
相關標籤/搜索