spring parse the source code parsing -ApplicationContext

ApplicationContext and BeanFactory bean container are the same, but Bean BeanFactory is the parent of all the container, inherited from the ApplicationContext BeanFactory (a subclass of BeanFactory inheritance)
ApplicationContext BeanFactory contains all the features and extends the other functions. Case ApplicationContext start to start, as follows:
ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
ctx.getBean("myBean");

 It can be seen ApplicationContext and BeanFactory usage is basically the same, after initialization can get directly Bean, and then we start with the ApplicationContext is initialized to start, that is, starting with the constructor ClassPathXmlApplicationContext the start code is as follows:

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
    }
. 1  public the ClassPathXmlApplicationContext (
 2              String [] configLocations, Boolean Refresh, @Nullable the ApplicationContext parent)
 . 3              throws BeansException {
 . 4  
. 5          // constructor call parent class 
. 6          Super (parent);
 . 7          // set the configuration XML 
. 8          setConfigLocations (configLocations);
 . 9          // the ApplicationContext initialization 
10          IF (Refresh) {
 . 11              Refresh ();
 12 is          }
 13 is      }

 

Xml initial configuration can be passed in the form of an array, a method is provided setConfigLocations code as follows:
 1 public void setConfigLocations(@Nullable String... locations) {
 2         if (locations != null) {
 3             Assert.noNullElements(locations, "Config locations must not be null");
 4             this.configLocations = new String[locations.length];
 5             for (int i = 0; i < locations.length; i++) {
 6                 this.configLocations[i] = resolvePath(locations[i]).trim();
 7             }
 8         }
 9         else {
10             this.configLocations = null;
11         }
12     }

 Xml mainly used for parsing the configuration information, the path information assigned to xml configLocations, provided it is necessary to perform an initialization operation after ApplicationContext configuration information, and the final step of the refresh method, as follows:

 1 @Override
 2     public void refresh() throws BeansException, IllegalStateException {
 3         synchronized (this.startupShutdownMonitor) {
 4             // Prepare this context for refreshing.
 5             //准备刷新
 6             prepareRefresh();
 7 
 8             // Tell the subclass to refresh the internal bean factory.
 9             //初始化BeanFactory,并进行XML文件读取
10             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
11 
12             //The use for the bean Factory PREPARE in the this context.
 13 is              // of the various function expansion BeanFactory 
14              prepareBeanFactory (beanFactory);
 15  
16              the try {
 . 17                  // android.permission POST-Processing Factory in context of the bean The subclasses.
 18 is                  // subclass A method of processing do extra cover 
. 19                  postProcessBeanFactory (beanFactory);
 20 is  
21 is                  // . Registered the Invoke Factory processors in AS Beans The context
 22 is                  // activate various BeanFactory processor 
23 is                  invokeBeanFactoryPostProcessors (beanFactory);
 24  
25                  //. Processors that the Register bean bean Creation Intercept
 26                  // Registration interception Bean Bean processor to create, just registered here, real time call in getBean of 
27                  registerBeanPostProcessors (beanFactory);
 28  
29                  // . The Initialize the Message Source for the this context
 30                  / / as the context initialization the message 
31 is                  initMessageSource ();
 32  
33 is                  // the initialize Event multicaster for the this context.
 34 is                  // initializes the application message broadcaster 
35                  initApplicationEventMulticaster ();
 36  
37 [                  // the initialize OTHER Special Beans specific context in subclasses.
 38 is                  //Left to initialize other subclasses of Bean 
39                  OnRefresh ();
 40  
41 is                  // the Check Register for listener Beans and Them.
 42 is                  // Find Lestener bean to bean, all registered in the register to the message broadcaster 
43 is                  registerListeners ();
 44 is  
45                  // . Instantiate All remaining (non-the lazy-the init) singletons
 46 is                  // initializes the remaining single embodiment the bean 
47                  finishBeanFactoryInitialization (beanFactory);
 48  
49                  // Last STEP: publish the Corresponding Event.
 50                  // complete refresh, notification processor refresh process life cycle, while others notice issued ContextRefreshEvent 
51                  finishRefresh ();
 52             }
53 
54             catch (BeansException ex) {
55                 if (logger.isWarnEnabled()) {
56                     logger.warn("Exception encountered during context initialization - " +
57                             "cancelling refresh attempt: " + ex);
58                 }
59 
60                 // Destroy already created singletons to avoid dangling resources.
61                 destroyBeans();
62 
63                 // Reset 'active' flag.
64                 cancelRefresh(ex);
65 
66                 // Propagate exception to caller.
67                 throw ex;
68             }
69 
70             finally {
71                 // Reset common introspection caches in Spring's core, since we
72                 // might not ever need metadata for singleton beans anymore...
73                 resetCommonCaches();
74             }
75         }
76     }
77 }

 

The main process is:
1. Before the initialization of the preparatory work, verification of system properties or environment variables
2. Initialize the BeanFactory, and xml file read, equivalent to reuse the BeanFactory configuration file reading resolution process is equivalent to an initialization BeanFactory, and the rest are extensions of the BeanFactory
3. BeanFactory filling function (such as @Autowired @Qualifier annotation support, etc.)
4. The method of subclass overrides the superclass additional processing (postProcessBeanFactory function is empty, extend convenient subclass)
The processor activating various BeanFactory
6. Register intercepted created bean bean processor
7. You can see the rest of the annotated code
 
Then look again, ready to verify before initialization skip directly to see how to initialize the BeanFactory,
1 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
2         refreshBeanFactory();
3         return getBeanFactory();
4     }

The first step initialization BeanFactory, be read parse xml configuration

The second step is returned BeanFactory

 1 @Override
 2     protected final void refreshBeanFactory() throws BeansException {
 3         if (hasBeanFactory()) {
 4             destroyBeans();
 5             closeBeanFactory();
 6         }
 7         try {
 8             DefaultListableBeanFactory beanFactory = createBeanFactory();
 9             beanFactory.setSerializationId(getId());
10             customizeBeanFactory(beanFactory);
11             loadBeanDefinitions(beanFactory);
12             synchronized (this.beanFactoryMonitor) {
13                 this.beanFactory = beanFactory;
14             }
15         }
16         catch (IOException ex) {
17             throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
18         }
19     }

 

Substantially as follows:
1. Create DefaultListableBeanFactory objects, BeanFactory initialization is actually created this object
2. Specify the serial number ID
3. Customize BeanFactory
4. Load BeanDefinition
The use of global variables recorded instances BeanFactory
 
Here customizeBeanFactory third step of the method is an extension of the BeanFactory, and added support @Qualifier of @Autowired
loadBeanDefinitions method is to load BeanDefinition, first of all it is to load the Xml, use loadBeanDefinitions method XmlBeanDefinitionReader logically registered and loaded BeanFactory configuration file as
 
Is an extension of BeanFactory BeanFactory after initialization, that is, after the method and content prepareBeanFactory
 
 1 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 2         // Tell the internal bean factory to use the context's class loader etc.
 3         beanFactory.setBeanClassLoader(getClassLoader());
 4         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
 5         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 6 
 7         // Configure the bean factory with context callbacks.
 8         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
 9         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
10         beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
11         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
12         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
13         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
14         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
15 
16         // BeanFactory interface not registered as resolvable type in a plain factory.
17         // MessageSource registered (and found for autowiring) as a bean.
18         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
19         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
20         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
21         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
22 
23         // Register early post-processor for detecting inner beans as ApplicationListeners.
24         beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
25 
26         // Detect a LoadTimeWeaver and prepare for weaving, if found.
27         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
28             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
29             // Set a temporary ClassLoader for type matching.
30             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
31         }
32 
33         // Register default environment beans.
34         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
35             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
36         }
37         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
38             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
39         }
40         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
41             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
42         }
43     }

 The method main contents are:

1. Add support for SPEL language (e.g., # {XXX.xxx} set properties)

2. Added support for Attribute Editor

3. Set-dependent function of the interface can be ignored

4. register some fixed-dependent properties

5. Increase support of AspectJ

6. attributes relating environment variables and singleton Register to Register

 
Next, look at the non-initialized embodiment of the single loading delay bean
 1 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
 2         // Initialize conversion service for this context.
 3         if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
 4                 beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
 5             beanFactory.setConversionService(
 6                     beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
 7         }
 8 
 9         // Register a default embedded value resolver if no bean post-processor
10         // (such as a PropertyPlaceholderConfigurer bean) registered any before:
11         // at this point, primarily for resolution in annotation attribute values.
12         if (!beanFactory.hasEmbeddedValueResolver()) {
13             beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
14         }
15 
16         // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
17         String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
18         for (String weaverAwareName : weaverAwareNames) {
19             getBean(weaverAwareName);
20         }
21 
22         // Stop using the temporary ClassLoader for type matching.
23         beanFactory.setTempClassLoader(null);
24 
25         // Allow for caching all bean definition metadata, not expecting further changes.
26         beanFactory.freezeConfiguration();
27 
28         // Instantiate all remaining (non-lazy-init) singletons.
29         beanFactory.preInstantiateSingletons();
30     }

 freezeConfiguration method 26 line here is to freeze the bean definition, that is to say it can not be changed after the registration of the bean, and the default ApplicationContext will say all singleton bean is initialized in advance, which is the method preInstantiateSingletons method

 1 @Override
 2     public void preInstantiateSingletons() throws BeansException {
 3         if (logger.isTraceEnabled()) {
 4             logger.trace("Pre-instantiating singletons in " + this);
 5         }
 6 
 7         // Iterate over a copy to allow for init methods which in turn register new bean definitions.
 8         // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
 9         List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
10 
11         // Trigger initialization of all non-lazy singleton beans...
12         for (String beanName : beanNames) {
13             RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
14             if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
15                 if (isFactoryBean(beanName)) {
16                     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
17                     if (bean instanceof FactoryBean) {
18                         final FactoryBean<?> factory = (FactoryBean<?>) bean;
19                         boolean isEagerInit;
20                         if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
21                             isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
22                                             ((SmartFactoryBean<?>) factory)::isEagerInit,
23                                     getAccessControlContext());
24                         }
25                         else {
26                             isEagerInit = (factory instanceof SmartFactoryBean &&
27                                     ((SmartFactoryBean<?>) factory).isEagerInit());
28                         }
29                         if (isEagerInit) {
30                             getBean(beanName);
31                         }
32                     }
33                 }
34                 else {
35                     getBean(beanName);
36                 }
37             }
38         }
39 
40         // Trigger post-initialization callback for all applicable beans...
41         for (String beanName : beanNames) {
42             Object singletonInstance = getSingleton(beanName);
43             if (singletonInstance instanceof SmartInitializingSingleton) {
44                 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
45                 if (System.getSecurityManager() != null) {
46                     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
47                         smartSingleton.afterSingletonsInstantiated();
48                         return null;
49                     }, getAccessControlContext());
50                 }
51                 else {
52                     smartSingleton.afterSingletonsInstantiated();
53                 }
54             }
55         }
56     }

 

 

High-frequency interview questions: the difference between ApplicationContext and BeanFactory?
1.BeanFactory is the parent of all container vessel interface, provide the most basic bean-related functions, and is the successor of the BeanFactory ApplicationContext, on the basis of the extended BeanFactory more features
2.ApplicationContext initialization process BeanFactory contains the initialization process, and how additional extension,
3.BeanFactory the bean is only initialized when acquired, while the ApplicationContext is initialized when he initialize all singleton bean (benefit is that when you start on it to check illegal bean)
Added support 4.ApplicationContext SPEL language (# {xx.xx} configuration etc.), message transmission, response mechanism (ApplicationEventPublisher), supported @Qualiiar and other annotations @Autowired
 

Guess you like

Origin www.cnblogs.com/jackion5/p/10991825.html