Spring源码解析(二)初始化环境

编程入门 行业动态 更新时间:2024-10-25 04:22:51

Spring源码解析(二)<a href=https://www.elefans.com/category/jswz/34/1770206.html style=初始化环境"/>

Spring源码解析(二)初始化环境

本章主要讲Spring初始化环境的方法,即refresh()方法
先来回顾一下AnnotationConfigApplicationContext的构造方法

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {//无参构造方法this();//注册方法register(componentClasses);//初始化环境方法refresh();}

当我们使用AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);这个方法时,会先对AnnotationConfigApplicationContext实例化,然后把该配置类注册到beanFactory中,接着就会对该环境进行初始化,先来看一下refresh方法

@Overridepublic 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.//准备BeanFactory,主要加一些后置处理器。prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.//这个方法目前什么都没做postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.//调用BeanFactoryPostProcessors后置处理器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主要是对一些属性做初始化,不重要可以跳过
从prepareBeanFactory这个方法开始看起

/*** 初始化BeanFactory* 配置factory的特性,比如classLoader,postProcesser,要忽略依赖,能够解析的依赖*/protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.//beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.//添加一堆后置处理器beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));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.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.//注册postprocessor用来检测内部bean如ApplicationListenersbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.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.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这个后置处理器进行详解
当我们有需求是在单例类中依赖原型类,因为单例类只会实例化一次,所以要使用的原型类一直是一个,会产生问题。这时我们可以让这个单例类实现ApplicationContextAware接口,每次调用原型类都从容器中获取,实现如下:
IndexDaoImpl原型类

@Repository("indexDaoImpl")
@Scope("prototype")
public class IndexDaoImpl implements IndexDao {@Overridepublic void query() {System.out.println("查询数据库111");}
}

IndexDaoImpl3单例类

@Repository
public class IndexDaoImpl3 implements ApplicationContextAware {private ApplicationContext applicationContext;public void query(){IndexDaoImpl indexDao = (IndexDaoImpl) applicationContext.getBean("indexDaoImpl");System.out.println(indexDao.hashCode());}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext=applicationContext;}
}

测试类Test

public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);IndexDaoImpl3 indexDaoImpl = (IndexDaoImpl3) ac.getBean("indexDaoImpl3");indexDaoImpl.query();indexDaoImpl.query();}
}

运行结果

可以看到不是同一个IndexDaoImpl。

那么原理是什么呢?
我们看到在prepareBeanFactory方法中添加了ApplicationContextAwareProcessor这个后置处理器,我们看这个类,可以看到postProcessBeforeInitialization方法执行了这段

private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}//如果bean是ApplicationContextAware的实现类,将applicationContext设置到里面if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}}

在这里设置的applicationContext供我们使用。
回到refresh()方法中,下一个方法是postProcessBeanFactory(beanFactory);目前这个方法是空方法,等待后续版本填充。
然后就到了非常非常重要的方法invokeBeanFactoryPostProcessors(beanFactory);
顾名思义就是执行BeanFactoryPostProcessors后置处理器的实现类。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
这里注意,getBeanFactoryPostProcessors()是得到我们自己实现的BeanFactoryPostProcessors,这里不能用@Component被Spring管理,必须要手动加入才能通过getBeanFactoryPostProcessors()得到。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("beanFactory");}
}

如果我们用@Component的方式,
用ac.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());才能获取。

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {//用于去重Set<String> processedBeans = new HashSet<>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;//这两个列表主要存储我们自己实现的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessorList<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();/*** 我们自己写的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor实现类* BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,是对BeanFactoryPostProcessor的扩展,* 所以下面要分别判断*/for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {//如果postProcessor是BeanDefinitionRegistryPostProcessor,加到registryProcessors队列中if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;//在这里已经将自己实现的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法执行到registryProcessor.postProcessBeanDefinitionRegistry(registry);//由于BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,所以我们应该registryProcessors.add(registryProcessor);}else {//如果postProcessor是BeanFactoryPostProcessor,加到regularPostProcessors队列中regularPostProcessors.add(postProcessor);}}//这里有new了一个队列,这里存的是Spring内部实现的BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();//得到beanFactory中BeanDefinitionRegistryPostProcessor实现类的beanName列表,Spring中只有一个,就是ConfigurationClassPostProcessorString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//循环遍历for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//添加到列表中currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}//排序sortPostProcessors(currentRegistryProcessors, beanFactory);//registryProcessors列表中添加,因为registryProcessors要在执行beanPostProcessor时用到registryProcessors.addAll(currentRegistryProcessors);//执行BeanDefinitionRegistryPostProcessors方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();//下面可以不用看,因为上面已经执行过postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}/*** 在上面执行的都是BeanDefinitionRegistryPostProcessor实现类的方法,下面要执行BeanFactoryPostProcessor的方法,* 因为BeanDefinitionRegistryPostProcessor实现类也是BeanFactoryPostProcessor的实现类,所以两个都要执行*/invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);/*** 我们自己的BeanFactoryPostProcessor实现类*/invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);//这个列表是得到Spring内部的BeanFactoryPostProcessor实现类。List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {//如果上面已经执行过,直接跳过()if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//添加到priorityOrderedPostProcessors列表中priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}//进行排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//进行调用invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);//下面可以不用再看List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);beanFactory.clearMetadataCache();}

invokeBeanFactoryPostProcessors方法很长很复杂,注释已经基本写全,可以对照一行一行研究。主要作用就是执行BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。
本篇博客写的内容已经够多,Spring中一个非常重要的后置处理器ConfigurationClassPostProcessor就是在这里调用到的,下一篇博客将详细介绍。

更多推荐

Spring源码解析(二)初始化环境

本文发布于:2024-03-12 22:52:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1732598.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:初始化   源码   环境   Spring

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!