Last article: Spring 5 source code analysis - register configuration class
Previously, the definition of configuration class has been registered in the container. Before comprehensive analysis and processing of configuration class, Spring needs to do some preprocessing, such as setting class loader, setting post processor ApplicationContextAwareProcessor, adding three objects of environment systemProperties systemEnvironment to the container, and setting Spring framework not to Operations such as interfaces that need to be injected automatically.
The source code is as follows:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Set class loader beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // It is very important to add BeanPostProcessor to complete the injection of Bean's related XXXAware interface beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // The following lines of code can ignore the given auto assembly dependent interfaces (that is, the auto injection of setter methods corresponding to these interfaces will not be executed) // For detailed documents, please refer to the blog: 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. //The following four lines of code are all subclasses of ApplicationContext, except beanfactory is the beanfactory added, // For example, annotation config application context. You need to get objects from beanFactory or annotationconfigpplicationcontext when performing automatic assembly 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. // Blog address: 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. // Add three objects of environment systemProperties systemEnvironment to the container 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));
It is easy to see that the postProcessBeforeInitialization method of ApplicationContextAwareProcessor is to set the corresponding Environment EmbeddedValueResolver ResourceLoader ApplicationEventPublisher MessageSource ApplicationContext object in the XXXAware interface class. You can read the relevant value pairs in your implementation class To intervene in the conduct of an operation or framework.
For example:
@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; } }
Three built-in beans (environment systemProperties systemEnvironment)
Since it is a built-in Bean, which exists in the Spring container, you can get the corresponding Bean by using automatic injection by type
For example, use EnvironmentAware to let the Spring framework call the setEnvironment() method of the implementation class through post-processing, but it can be written in a different way
public class IgnoreUser implements /*EnvironmentAware, */ApplicationContextAware { @Autowired private Environment environment;
Note out the implements EnvironmentAware interface, and use @ Autowired directly