简单探究spring加载bean过程

2019-5-5 09:45:18

  1. 举例按照
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“META-INF/spring/simplified-provider.xml”});
    DemoService s=(DemoService)context.getBean(“demoService”);

Xml配置如下”

  1. 进入ClassPathXmlApplicationContext构造函数
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
    refresh();
    }
    super(parent)获取的是父类spring上下文, 由于parent参数为null,此处无意义,
    setConfigLocations(configLocations),将spring占位符${}号,替换为真正的value
    关键是refres方法,由于本类没有实现,调用的是父类中的方法AbstractApplicationContext(父类 )

2.进入AbstractApplicationContext父类查看,refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		}

		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();
		}
	}
}

① prepareRefresh()
② ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
<1>先去父类AbstractRefreshableApplicationContext中执行方法 refreshBeanFactory(),判断是否存在工厂,若已经存在,销毁所有bean,并且关闭工厂.
然后创建工厂实例DefaultListableBeanFactory
<2> loadBeanDefinitions(beanFactory),bean工厂加载bean定义对象,在父类AbstractXmlApplicationContext中处理,创建bean定义读取器XmlBeanDefinitionReader对象,加载bean信息到
Beanfactory的beanDefinitionMap中,
例如: “demoService” -> “Generic bean: class [org.apache.dubbo.samples.simplified.registry.nosimple.impl.DemoServiceImpl]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/simplified-provider.xml]”
[05/05/19 10:46:32:032 CST] main INFO xml.XmlBeanDefinitionReader: Loading XML bean definitions from class path resource [META-INF/spring/simplified-provider.xml]
[05/05/19 10:49:22:022 CST] ZooKeeper Server Starter INFO server.ServerCnxnFactory: Using org.apache.zookeeper.server.NIOServerCnxnFactory as server connection factory
[05/05/19 10:49:22:022 CST] ZooKeeper Server Starter INFO server.NIOServerCnxnFactory: binding to port 0.0.0.0/0.0.0.0:2181
[05/05/19 10:49:22:022 CST] main DEBUG xml.DefaultDocumentLoader: Using JAXP provider [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl]
[05/05/19 10:49:22:022 CST] main DEBUG xml.PluggableSchemaResolver: Found XML schema [http://www.springframework.org/schema/beans/spring-beans-4.3.xsd] in classpath: org/springframework/beans/factory/xml/spring-beans-4.3.xsd

③ prepareBeanFactory(beanFactory); // Prepare the bean factory for use in this context.
<1>bean后处理器处理

④ postProcessBeanFactory(beanFactory); // Allows post-processing of the bean factory in context subclasses. 在子类中实现,bennfactory后处理器,加载特异话的beanfactory后处理器, ClassPathXmlApplicationContext并没有重写该方法

⑤ invokeBeanFactoryPostProcessors(beanFactory); // Invoke factory processors registered as beans in the context.
调用beanfactory后处理器,创建为bean对象,处理bean工厂创建后的一些特异化操作

⑥ registerBeanPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
//注册拦截bean创建的bean处理器。即bean后处理器.
/**实例化并调用所有注册的beanPostProcessor bean,遵守明确的命令。

必须在应用程序bean的任何实例化之前调用。*/

⑦ initMessageSource();// Initialize message source for this context.若没有,会创建默认

⑧ initApplicationEventMulticaster();// Initialize event multicaster for this context. 为上下文初始化 多播器事件 若没有,会创建默认

⑨ onRefresh();// Initialize other special beans in specific context subclasses. 初始化特定上下文子类中的其他特殊bean。
ClassPathXmlApplicationContext子类中没有重写此方法,所以此处为空实现.

⑩ registerListeners();// Check for listener beans and register them. 注册监听器对象

⑪ finishBeanFactoryInitialization(beanFactory); // Instantiate all remaining (non-lazy-init) singletons.
实例化所有剩余的(非lazy init)单例,非常重要
<1>.先初始化loadtimeweaveraware bean以允许尽早注册其转换器,跟AOP相关
<2> 在DefaultListableBeanFactory中执行preInstantiateSingletons方法,开始准备实例化bean,最终通过反射,最底层反射估计借用了其他语言,最终生成对象的类为NativeConstructorAccessorImpl extends ConstructorAccessorImpl
在private static native Object newInstance0(Constructor<?> c, Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException;

猜你喜欢

转载自blog.csdn.net/weixin_42267383/article/details/89888880