Spring源码阅读 (二):Bean 的生命周期.AnnotationConfigApplicationContext

1.建一个测试model

在源码项目里新建一个model,源码编译参考上一篇

建完model后在java包下添加三个类,执行成功就可以了就可以开始进行源码阅读了

这里提一下还有一个ClassPathXmlApplicationContext,这个就是通过上下文去初始化Spring环境

public class Test {
	public static void main(String[] args) {
	    //注解去初始化Spring环境
		AnnotationConfigApplicationContext applicationContext =
				new AnnotationConfigApplicationContext(MyAppConfig.class);
		System.out.println(applicationContext.getBean(CityService.class));
	}
}

@Configuration
@ComponentScan("com.demo.spring")
public class MyAppConfig {
}

@Component
public class CityService {
}

Bean的生命周期

首先我们使用IDEA点进去看一下AnnotationConfigApplicationContext,这个就是通过注解来配置Spring的上下文环境

//载入解析注册的过程

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//父类构造函数里,创建了一个Bean工厂
		// this.beanFactory = new DefaultListableBeanFactory()
		this();
		//读取和扫描器,将BeanDefinition方到Map里
		register(annotatedClasses);

		refresh();
	}

1.首先是this方法,this方法干了一个什么事情呢?
首先这个无参构造方法里面呢

        public  AnnotationConfigApplicationContext() {
        //创建一个读取Bean定义的处理器,BeanDefinition
		this.reader = new AnnotatedBeanDefinitionReader(this);
		//扫描类转换成BD
		//仅仅为了程序员去使用AnnotationConfigApplicationContext
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

调用子类构造方法也会调用父类构造方法

public GenericApplicationContext() {
         //实例化一个工厂
		this.beanFactory = new DefaultListableBeanFactory();
	}

Spring工厂:
理论:产生Bean
如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身

2.之后是register(annotatedClasses);方法他做了什么呢
将传入的appConfig.class变成BeanDefinition

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//根据指定的Bean创建一个AnnotatedGenericBeanDefinition
		//这个AnnotatedGenericBeanDefinition可以理解为一个数据结构
		//包含了类的其他信息
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		//判断这个类是否要跳过解析
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		//得到类的作用域
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		//类的作用域添加到数据结构的结构当中
		abd.setScope(scopeMetadata.getScopeName());
		//生产Bean的名字
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//如果想容器注册注解定义时,使用了额外的限定符注解则解析
		//qualifiers是包含了注解数组
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				//加Primary设为首选
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				} else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				} else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}
		//也是一个数据结构
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		//就是把definitionHolder一个DefaultListableFactory,registry就是ApplicationContext
		//点进代码看到map.put
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

3.最后是refresh();这个是SpringFramework里一个主要的代码说是最主要也不为过。这里呢一共调用了12个方法

@Override
	public void refresh() throws BeansException, IllegalStateException {
		//同步的方法
		synchronized (this.startupShutdownMonitor) {

			// 1.Prepare this context for refreshing.
			prepareRefresh();

			// 2.Tell the subclass to refresh the internal bean factory.
			// 刷新beanFactory,删除旧的beanFactory,创建新的beanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3.Prepare the bean factory for use in this context.
			//准备bean工厂以供在此上下文中使用。
			prepareBeanFactory(beanFactory);

			try {
				// 4.Allows post-processing of the bean factory in context subclasses.
				//允许在上下文子类中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				// 5.Invoke factory processors registered as beans in the context.
				// 调用工厂处理器,解析类信息 生成Bean
				// 执行自定义的processBean ,扫描Bean 处理了import
				// 扫描->putMap(RootBeanDefinition)->(1.custom)
				// 程序员可以,先处理自定义的,先处理order的

				invokeBeanFactoryPostProcessors(beanFactory);

				// 6Register bean processors that intercept bean creation.
				//注册BeanPostProcessor前后
				registerBeanPostProcessors(beanFactory);

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

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

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

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

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

(1)prepareRefresh();
//启动事件标识位
// 设置环境变量和容器的开关标志

(2)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//要对工厂进行初始化

(3)准备工厂

(4)postProcessBeanFactory(beanFactory);
//允许在上下文子类中对bean工厂进行后处理。

(5)invokeBeanFactoryPostProcessors(beanFactory);

  1.扫描了符合要求的class文件,各种Import注解
2.解析成BeanDefinition
ps:之前的register也是扫描 但是放入了appConfig.class 也就是AnnotationConfigApplicationContext传入的配置类
3.put->BeanDefinitionMap->调用自定义的BeanFactoryPostProcesser,还有内置的。
/**
 * 扩展原理:
 * BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
 * 
 * 1、BeanFactoryPostProcessor:beanFactory的后置处理器;
 *         在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
 *         所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
 * 
 * 
 * BeanFactoryPostProcessor原理:
 * 1)、ioc容器创建对象
 * 2)、invokeBeanFactoryPostProcessors(beanFactory);
 *         如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
 *             1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
 *             2)、在初始化创建其他组件前面执行
 * 
 * 2、BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
 *         postProcessBeanDefinitionRegistry();
 *         在所有bean定义信息将要被加载,bean实例还未创建的时候;
 *         优先于BeanFactoryPostProcessor执行;
 *         利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件;
 * 
 *     原理:
 *         1)、ioc创建对象
 *         2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
 *         3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
 *             1、依次触发所有的postProcessBeanDefinitionRegistry()方法
 *             2、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
 * 
 *         4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法
 *     

(11)finishBeanFactoryInitialization(beanFactory);
实例化也就是new
beanFactory.preInstantiateSingletons();

//log级别
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		//所有Bean的名字
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//触发所有非懒加载的单例Beans
		for (String beanName : beanNames) {
            //bdmap.get
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						} else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				} else {
					//实例Bean放到单例池里 单例池是一个ConcuretHashMap
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				} else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章