文章目录
前言
上一篇介绍了源码结构以及Spring容器内部成员,本文着重分析学习spring容器启动的主流程过程:如下代码的整个流程,以及在这个过程中可以运用在实际工作中的知识点。(文中涉及到的概念如BeanDefinition,BeanDefinitionHolder等等如不清楚请移步上文末尾翻阅)
- AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
- context.register(AppConfig.class);
- context.refresh();
主流程分析一:new AnnotationConfigApplicationContext()
实例化上下文,准备AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,简称reader和scanner。
reader:是一个BeanDefinition读取器,给一个类给他,他帮你转换成为BeanDefinition。在此期间,Spring把一些bean变成了BeanDefinition,比如ConfigurationClassPostProcessor等等6个类,用于后续流程使用。
scanner:能够扫描一个类、包,并且转换成BeanDefinition。源码这里是没有使用这个对象,源码使用的是spring自己new的一个ClassPathBeanDefinitionScanner。这个对象用于程序员手动调用scan方法进行扫描包。这里不过多阐述。
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// scanner用来扫描包或者类,继而转换成bd
// 实际上扫描包不是scanner这个对象
// 是spring自己new的一个ClassPathBeanDefinitionScanner
// 这里的scanner是提供给程序员手动调用scan方法的一个类AnnotationConfigApplicationContext.scan
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
下面看一下AnnotatedBeanDefinitionReader干了些什么:
着重看一下AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 通过registry环境获取beanfactory空的工厂
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// 给工厂添加一些原料
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
// AnnotationAwareOrderComparator主要能解析@order注解和@priority (排序)
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// BeanDefinitionHolder包含beanDefinition和beanname,主要用于方便封装参数
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// beanDefinition的注册,注册ConfigurationClassPostProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 这里ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
// BeanDefinitionRegistryPostProcessor实现BeanFactoryPostProcessor接口
// 把一个普通类实例化一个BeanDefinition
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// BeanDefinition放进beanDefinitionMap以及BeanDefinitionHolder(BeanDefinitionRegistry的registerBeanDefinition方法)
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// beanDefinition的注册,注册AutowiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
// beanDefinition的注册,支持JSR-250,则注册CommonAnnotationBeanPostProcessor
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// beanDefinition的注册,支持JPA,则注册PersistenceAnnotationBeanPostProcessor
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// beanDefinition的注册,注册EventListenerMethodProcessor
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// beanDefinition的注册,注册DefaultEventListenerFactory
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
由代码和注释可知道,Spring的reader流程如下:
- 1.从容器中取一个beanFactory工厂,如果beanFactory不为空则为工厂添加一些原料,如AnnotationAwareOrderComparator:提供排序的一些功能。ContextAnnotationAutowireCandidateResolver:提供处理延迟加载的功能
- 2.实例化一个元素为BeanDefinitionHolder的set集合,BeanDefinitionHolder包含beanDefinition和beanname,主要用于方便封装参数
- 3.注册6个类为beanDefinition,并将它们添加至第二步的set集合以及beanDefinitionMap中,用于后续使用。(ConfigurationClassPostProcessor类后面重点关注)
其中分别为:ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,EventListenerMethodProcessor,DefaultEventListenerFactory。
我们看一下源码中Spring是如何把一个类变为BeanDefinition的,以及如何放入beanDefinitionMap和BeanDefinitionHolder:
RootBeanDefinition 是BeanDefinition接口的一个实现,我们只需要把要转换的类的class放入构造器即可,下面例子是ConfigurationClassPostProcessor类。
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
// beanDefinition的注册,注册ConfigurationClassPostProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 把一个普通类实例化一个BeanDefinition
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// BeanDefinition放进beanDefinitionMap以及BeanDefinitionHolder(BeanDefinitionRegistry的registerBeanDefinition方法)
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 核心
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
核心在于registry.registerBeanDefinition(beanName, definition);接口有3个实现,最终关键代码都是:
this.beanDefinitionMap.put(beanName, beanDefinition);放入beanDefinitionMap
放入beanDefinitionMap之后,就是实例化BeanDefinitionHolder,并把它装入第二步流程中的set集合
主流程分析二:context.register(AppConfig.class);
AppConfig类:
@Configuration
@ComponentScan("com.demo")
public class AppConfig {
}
context.register:把AppConfig类注册为一个BeanDefinition,然后放到DefaultListableBeanFactory的beanDefinitionMap里面
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
//核心
this.reader.register(componentClasses);
registerComponentClass.end();
}
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
//核心
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
核心方法doRegisterBean:
1.解析传入的类class,用这个class实例化AnnotatedGenericBeanDefinition 对象,这个类是BeanDefinition接口的第二个实现
2.BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
调用registry的registerBeanDefinition,把实例化的AnnotatedGenericBeanDefinition 放入beanDefinitionMap和BeanDefinitionHolder
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 调用registry的registerBeanDefinition,把beanDefinition放入beanDefinitionMap
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
主流程分析三:context.refresh();
context.refresh():准备好bean工厂,实例化对象
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备工作包括设置启动时间,是否激活标识位
// 初始化属性源(property,source)配置
prepareRefresh();
// 返回一个beanFactory,因为即将对工厂进行初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备工厂
prepareBeanFactory(beanFactory);
try {
// 无任何处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 执行一些已经注册过的BeanFactoryPostProcessor方法
// 设置执行自定义的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessors
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
// 注册监听器
registerListeners();
//完成工厂初始化
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
contextRefresh.end();
}
}
}
这里我们着重关注prepareBeanFactory准备工厂和invokeBeanFactoryPostProcessors执行一些已经注册过的BeanFactoryPostProcessor方法(即:reader里面注册过的ConfigurationClassPostProcessor等等)
prepareBeanFactory准备工厂:配置一些标准的特征,比如上下文加载器以及回调的后置处理器
- 1、添加一个类加载器
- 2、添加bean表达式解释器,为了能够让我们的beanFactory去解析bean表达式,比如jsp页面el表达式
- 3、添加一个后置处理器ApplicationContextAwareProcessor
- 4、添加了自动注入别忽略的列表
- 5、对象的依赖替换
- 6、添加了一个ApplicationListenerDetector后置处理器
- 7、加载一些默认环境和系统配置
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 1.添加一个类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
// 2.添加bean表达式解释器,为了能够让我们的beanFactory去解析bean表达式 比如el表达式获取bean里面的属性在页面
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 对象与字符串的转换
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 3.添加一个后置处理器ApplicationContextAwareProcessor,能在bean中获取各种*aware。
// 会在bean的实例化过程中依次执行list里面的各种后置处理器Processor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4.添加了一些自动注入被忽略的列表
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.ignoreDependencyInterface(ApplicationStartup.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 对象的依赖替换,比如依赖BeanFactory这么一个类,就用beanFactory替换它
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.
// 5.添加一个后置处理器ApplicationListenerDetector(基本不怎么用)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 加载一些时间相关
if (!IN_NATIVE_IMAGE && 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.
// 加载一些默认的环境配置。系统配置和系统环境配置
// systemProperties systemEnvironment
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
invokeBeanFactoryPostProcessors:执行一些已经注册过的(ConfigurationClassPostProcessor)和自定义的BeanFactoryPostProcessor
首先学习一个知识点:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor,拓展了一个postProcessBeanDefinitionRegistry方法。
reader流程中添加的6个类:
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口
其他5个是实现BeanFactoryPostProcessor接口
1.此方法传了2个参数,分别是工厂beanFactory,以及程序员手动添加的beanFactoryPostProcessors
2.定义了3个list:
- 存放BeanFactoryPostProcessor:List<<>BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
- 存放BeanDefinitionRegistryPostProcessor:List<<>BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
- 存放程序员自定义和spring内部自己的BeanDefinitionRegistryPostProcessor汇总的list:List<<>BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
流程:
- 1.拆分程序员自定义的BeanFactoryPostProcessor分别放入BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的相关list,并且如果是BeanDefinitionRegistryPostProcessor,则执行拓展方法postProcessBeanDefinitionRegistry(程序员手动添加的)
- 2.通过getBeanNamesForType方法从工厂beanFactory获取BeanDefinitionRegistryPostProcessor类型的bean名字,并通过名字获取bean,放入存放BeanDefinitionRegistryPostProcessor的list
- 3.排序spring内部的BeanDefinitionRegistryPostProcessor类型的list
- 4.汇总spring内部和程序员自定义的BeanDefinitionRegistryPostProcessor类型的集合
- 5.执行spring内部的BeanDefinitionRegistryPostProcessor中拓展postProcessBeanDefinitionRegistry方法(spring内部的)
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 自定义的BeanFactoryPostProcessors.
// 拆分为存放BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的2个list,
// spring为什么要拆分?因为BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor接口,前者有拓展的功能,分开处理
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 放的spring内部实现的BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 通过type类型获取bean的名字,type指的BeanDefinition中描述当前类的class类型
// ConfigurationClassPostProcessor就是属性BeanDefinitionRegistryPostProcessor这个类型
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 这里获取了n个在之前reader的时候配置的spring内部的BeanFactoryPostProcessor后置处理器,用于现在插手spring实例化bean的过程
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并自定义和spring内部的list
registryProcessors.addAll(currentRegistryProcessors);
/**
* BeanFactoryPostProcessors方法调用****执行postProcessBeanDefinitionRegistry拓展方法
* 注意是拓展方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
......
......
}
}
下面看一看程序员如何手动传入BeanFactoryPostProcessor呢???
只需要调用上下文的addBeanFactoryPostProcessor方法,传入自己构造的BeanFactoryPostProcessor就行了
context.addBeanFactoryPostProcessor(new MyBeanFactoryProcessor());
那么在这里,小伙伴有没有发现一个很牛逼的一点:我们居然已经可以插手spring容器的启动过程了???因为这里自定义一个MyBeanFactoryProcessor,我们把容器的userDaoImpl bean改为了原型prototype,每次获取的都是不同的bean
由此,本文的学习就这里,下文将着重分析学习ConfigurationClassPostProcessor类的作用。
上一篇:Spring源码学习(一) | 源码结构以及Spring容器内部成员概述