preface
Spring, as a container, manages the life cycle of objects and the dependencies between objects. Configuration files are used to define objects and set their dependencies with other objects.
The main test class
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Bean bean = applicationContext.getBean(Bean.class);
System.out.println(bean);
}
Copy the code
ClassPathXmlApplicationContext class
-
Once the application is created, it can be rebuilt through Refresh (), which destroys the original application and then re-initializes it
-
A constructor
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); // Set the configuration file setConfigLocations(configLocations); If (refresh) {// Core method refresh(); }}Copy the code
AbstractApplicationContext class
The refresh method
@override public void refresh() throws BeansException, IllegalStateException { Prevent you from broken in the process of initialization synchronized (enclosing startupShutdownMonitor) {/ / preparation prepareRefresh (); // The configuration file is split into Bean definitions registered in the BeanFactory. / / is the Map < beanName beanDefinition > ConfigurableListableBeanFactory the beanFactory = obtainFreshBeanFactory (); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); // If you implement the BeanFactoryPostProcessor interface, You can do something at initialization postProcessBeanFactory(beanFactory); // Invoke Factory Processors registered as beans in the context InvokeBeanFactoryPostProcessors postProcessBeanFactory (factory) method (the beanFactory); // Register bean processors that intercept bean creation. Note the difference between BeanFactoryPostProcessor and This interface: PostProcessBeforeInitialization and postProcessAfterInitialization / / two methods in the Bean initialization respectively before and after the initialization are implemented. Note that Bean here haven't initialize registerBeanPostProcessors (the beanFactory); // Initialize MessageSource(); // Initialize MessageSource(); / / Initialize event multicaster for this context. / / Initialize the current ApplicationContext event broadcast initApplicationEventMulticaster (); // Initialize other special beans in specific context subclasses. // Concrete subclasses can initialize some special beans here (before initializing Singleton beans) onRefresh(); // Check for listener beans and register them. // The listeners are registered on ApplicationListener interfaces registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. Non - except lazy / / main methods finishBeanFactoryInitialization (the beanFactory); Corresponding event (); // Corresponding event (); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); }}}Copy the code
ObtainFreshBeanFactory () method
1, initialize the BeanFactory – “DefaultListableBeanFactory. Class
DefaultListableBeanFactory beanFactory = createBeanFactory();
Copy the code
2. Define factory properties: whether Bean overrides are allowed, and whether circular references are allowed
Load the Bean to BeanFactory – loadBeanDefinitions() method
3.1 Reading, checking, and parsing XML configuration files
preProcessXml(root); // Hook parseBeanDefinitions(root, this.delegate); // The main code: put the information in the relevant map of Factory postProcessXml(root); / / hooksCopy the code
3.2 Put the XML configuration file information into the factory map.
ParseBeanDefinitions () = > DefaultListableBeanFactory. Class registerBeanDefinition () method
this.beanDefinitionMap.put(beanName, beanDefinition); / / beanName collection, and the Map key (beanName) corresponding to this. BeanDefinitionNames. Add (beanName);Copy the code
The factory has several maps that store objects read from XML as map <beanName, beanDefinition>. And a list that holds all the Beannames.
A beanDefinition is just a description of a class, and it’s a long way from what we need.
4. Return the factory that carries various information
FinishBeanFactoryInitialization () method
Initialize all Singletons according to the factory, except non-lazy
1. Initialize the special class.
2. Caching. Or DefaultListableBeanFactory. Class. Brought before we talked about above beanName List into an array into frozenBeanDefinitionNames.
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
Copy the code
3. Initialization.
3.1 Get the List with beanName and iterate through the loop
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
Copy the code
3.2 Special class FactoryBean and other special processing, not expanded.
3.3 Entering Object Instantiation.
AbstractBeanFactory class doGetBean doCreateBean AbstractAutowireCapableBeanFactory class () method ()
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { ... If (instanceWrapper == null) {// Here to instantiate the Bean, instanceWrapper = createBeanInstance(beanName, MBD, args); }... }Copy the code
CreateBeanInstance AbstractAutowireCapableBeanFactory class ()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {// Make sure bean class is actually resolved at this point. > beanClass = resolveBeanClass(mbd, beanName); If (beanClass! = null && ! Modifier.isPublic(beanClass.getModifiers()) && ! mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } if (mbd.getFactoryMethodName() ! = null) {/ / the factory method instantiation, pay attention to, not a FactoryBean return instantiateUsingFactoryMethod (beanName, MBD, args); } // Shortcut when re-creating the same bean... // If it is not created for the first time, for example, create the Prototype bean for the second time. // In this case, we can know from the first creation whether to use the constructor with no arguments or dependency injection. boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod ! = null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; Error (resolved) {error (resolved) {return autowireConstructor(beanName, MBD, null, null); } else {return instantiateBean(beanName, MBD); } } // Candidate constructors for autowiring? // Determine whether to use the parameterized Constructor<? >[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors ! = null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || ! Objectutils.isempty (args)) {return autowireConstructor(beanName, MBD, ctors, args); } // No special handling: simply use no-arg constructor. }Copy the code
InstantiateClass AbstractAutowireCapableBeanFactory class ()
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() ! = null) { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else {// instantiate beanInstance = getInstantiationStrategy().instantiate(MBD, beanName, parent) } // return BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); }}Copy the code
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); return ctor.newInstance(args); // The constructor initializes the object}... }Copy the code
The last
Thank you for reading here, the article has any shortcomings please correct, feel the article is helpful to you remember to give me a thumbs up, every day will share Java related technical articles or industry information, welcome to pay attention to and forward the article!