用了Spring很久了,也没怎么仔细求看下源码,就算偶尔也是在网上看到别人的分析,每个点都说的明明白白,清清楚楚,每一个点都有中文解释,每个方法的作用,但是别人写的文章再好,终究不是自己分析的,怎么也记不住。
下面这里就用一个简单的例子来探寻Spring实例化bean执行源码的主脉络,也不会过多的解释每个方法的作用,只是单纯的找到为啥加个@Component注解,就能够实例化为bean对象。
一、环境搭建
可以参考https://www.suibibk.com/topic/744968214315794432 搭建一个注解版的spring环境,配置文件版的现在用的很少了,这里就不说先了,其实可以柴刀无非就是解析配置文件变成配置类呗!
二、源码分析
1、配置类
注解模式一般需要一个配置类
@Configuration@ComponentScan(basePackages = "com.suibibk.spring")public class SpringConfiguration {//spring容器初始化时,会调用配置类的无参构造函数public SpringConfiguration(){System.out.println("容器启动初始化");}}
@Configuration 表明这个是一个配置类,就相当于之前的配置文件
@ComponentScan(basePackages = “com.suibibk.spring”) 说明需要扫描的包路径,也就是说com.suibibk.spring下的类和子类都会被扫描,然后检查有没有相关注解,比如@Component 或者@Imports等。
2、Bean
这里建一个bean用来测试
package com.suibibk.spring;@Componentpublic class User {private String username;private String password;public String getInfo() {return username+";"+password;}}
我们User类是在com.suibibk.spring下面的,也就是在我们的包扫描路径下,应该会被实例化成bean.
3、启动测试
public class App {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);}}
这里用AnnotationConfigApplicationContext模式来启动。
我这里呢,并不会去列出各种类之间的继承关系,就靠看源码来推测即可,后续有时间再分析下继承关系,看源码有两中方法,一种是静态,一种是动态调试,静态看比较难,要连蒙带猜,不要转牛角尖,想要去了解每一行代码。
我看源码的经验,就是带着目的去,比如我这边文章看源码的目的就是想要弄清楚spring是怎么把扫描包下面的所有加了@Component注解的类都实例化的,所以我只会关注这个问题,至于其他的AOP,事务,等等,暂时不考虑,不然会迷失在源码里。
注:找到看源码的目的,剥离主线,跳过不理解或者无关紧要的部分。
下面开始来阅读源码,可以选择静态阅读或者动态阅读,正常来说都可以静态了解一下,再动态走一遍。
目的:找到Spring如何实例化扫描包下面加了@Component注解的类。
4、怎么解析配置类的?
我们知道,我们的扫描包所在的路径就在配置类里,所以怎么解析配置类的呢?肯定只有解析了配置类才能够继续找到@ComponentScan(basePackages = “com.suibibk.spring”) 继而找到com.suibibk.spring下面的User。
首先我们看开始的代码
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
很简单,这里就是传入配置类,然后就一切都搞定了,大道至简~,我们跟踪进去
/*** Create a new AnnotationConfigApplicationContext, deriving bean definitions* from the given component classes and automatically refreshing the context.* @param componentClasses one or more component classes — for example,* {@link Configuration @Configuration} classes*/public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();}
这里面,讲真表示啥都看不懂,那就只能一行行跟进去,我们看看this()方法干了啥
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
按字面意思来说,就是创建了一个reder和一个scanner对象,不过这两个都穿了个this对象,也就是AnnotationConfigApplicationContext,我们再看看这个类的定义
public class AnnotationConfigApplicationContext extends GenericApplicationContext
有继承类,那么肯定是先调用GenericApplicationContext的构造方法,跟进去看看
/*** Create a new GenericApplicationContext.* @see #registerBeanDefinition* @see #refresh*/public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}
这里简单的实例化了一个beanFactory,类型是DefaultListableBeanFactory,也不知到干啥的,我看很多源码分析的都一下就把类结构说明了,但是如果你从零开始看源码你是一脸懵逼的,只能先大概记下来,这里实例化了一个DefaultListableBeanFactory。
我们下看看
this.reader = new AnnotatedBeanDefinitionReader(this);
这行代码,看看里面干了啥,其实我看这里的时候,对里面的逻辑没啥期待,肯定跟我的目的没太大关系,毕竟this()方法根本就没有传我的配置类SpringConfiguration,但还是要大概点进去看看,go~
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}
这里我们要知道registry就是AnnotatedBeanDefinitionReader对象,然后看
getOrCreateEnvironment(registry)
感觉跟创建环境有关的这里先直接掠过,看this
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);}
一眼就看到
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
可能有点有意义事情,毕竟字面意思是注册注解配置处理器,一路跟踪进去
AnnotationConfigUtils.java
/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on*/public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);}
看解释是什么注册所有的相关的注解post processors(后处理程序),其实看到这里可能就会联想到浙西而处理器的作用就是对bean实例化后进行处理的,为啥会这么说呢,我们看源码肯定是知道了一个框架的大概使用方法使用细节才会到看源码的底部,如果用都不会用,也就没有必要谈论看源码的事情了,我们知道spring中有一类BeanPostProcessor,只要实现了BeanPostProcessor,那么这个类里面的方法就会被调用,例如!
@Componentpublic class MyBeanPostProcessors implements BeanPostProcessor{public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("MyBeanPostProcessors#postProcessBeforeInitialization:"+beanName);return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("MyBeanPostProcessors#postProcessAfterInitialization:"+beanName);return bean;}}
那么运行程序
MyBeanPostProcessors#postProcessBeforeInitialization:userMyBeanPostProcessors#postProcessAfterInitialization:user
会在user实例化的时候先调用before然后再调用after,
所以这里需要留意,可能我们到这里也不清楚具体有什么作用,但是先记下,继续跟踪代码
/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on* @param source the configuration source element (already extracted)* that this registration was triggered from. May be {@code null}.* @return a Set of BeanDefinitionHolders, containing all bean definitions* that have actually been registered by this call*/public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}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.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.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));}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));}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;}
前一步分析说,是注册一批后处理器,这里可以看到
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
应该是有8个,具体是哪8个呢,又注册到哪里了呢?很明显,分别是
/*** The bean name of the internally managed Configuration annotation processor.*/public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
看注释作用大概是内部管理配置注解的处理器,难道是管理Configuration的处理器?这里猜测
/*** The bean name of the internally managed Autowired annotation processor.*/public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
内部管理Autowired注解的处理器,难道是依赖注入的时候来处理@Autowired 自动装配注解的处理器?
/*** The bean name of the internally managed JSR-250 annotation processor.*/public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalCommonAnnotationProcessor";
JSR-250 annotation 是什么注解,没用过,跳过,注意,这里一定不要赚牛角尖,不要一定每一行都要理解,我们的目的是spring解析配置类然后解析扫描包下面的所有bean的过程,上面这个知识看源码的时候觉得可能有关,所以这里最好的方法就是看不懂的就跳过,大概猜测下是JSR-250注解什么的。
继续
/*** The bean name of the internally managed JPA annotation processor.*/public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
管理JPA注解,工作中用的比较少,这里也不管先
/*** The bean name of the internally managed @EventListener annotation processor.*/public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME ="org.springframework.context.event.internalEventListenerProcessor";
@EventListener 事件监听?可能是用语管理事件监听的注解处理器,继续跳过
/*** The bean name of the internally managed EventListenerFactory.*/public static final String EVENT_LISTENER_FACTORY_BEAN_NAME ="org.springframework.context.event.internalEventListenerFactory";
事件监听工厂?不懂!
额感觉这里才6个,不管先,反正知道大概要把一批后值处理器都放到registry里,也就是AnnotationConfigApplicationContext里,具体放到哪里呢?
我们大概跟踪下代码进去
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
我们根据源码可以知道,基本上都把这些处理器都变成一个RootBeanDefinition对象,然后执行
registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
方法来注册到registry,这个方法返回的是一个BeanDefinitionHolder,因为我们上面设置的set就是这个对象。继续跟踪代码
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(beanName, definition);return new BeanDefinitionHolder(definition, beanName);}
很明显看到是方法registerBeanDefinition
GenericApplicationContext.java
@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {this.beanFactory.registerBeanDefinition(beanName, beanDefinition);}
这里用了beanFactory,我们前面知道,beanFactory是DefaultListableBeanFactory
DefaultListableBeanFactory.java
@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}else if (existingDefinition.getRole() < beanDefinition.getRole()) {// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}}else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);}else if (isConfigurationFrozen()) {clearByTypeCache();}}
大改浏览下,找到这一行代码
this.beanDefinitionMap.put(beanName, beanDefinition);
beanDefinitionMap
/** Map of bean definition objects, keyed by bean name. */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
是一个线程安全的ConcurrentHashMap key是bean的名字,值是BeanDefinition,而BeanDefinition如下
SCOPE_SINGLETON : StringSCOPE_PROTOTYPE : StringROLE_APPLICATION : intROLE_SUPPORT : intROLE_INFRASTRUCTURE : intsetParentName(String)getParentName()setBeanClassName(String)getBeanClassName()setScope(String)getScope()setLazyInit(boolean)isLazyInit()setDependsOn(String...)getDependsOn()setAutowireCandidate(boolean)isAutowireCandidate()setPrimary(boolean)isPrimary()setFactoryBeanName(String)getFactoryBeanName()setFactoryMethodName(String)getFactoryMethodName()...
这,不就是一个spring容器对象对应的类的属性么,比如isLazyInit()是否是懒加载,getScope()作用域,看到这里不由自主的怀疑:难道spring的所有加了@Compontent注解的类都会被解析为BeanDefinition对象放到GenericApplicationContext(AnnotationConfigApplicationContext继承的类)中的对象DefaultListableBeanFactory中的变量beanDefinitionMap中,key是bean的名字,值是这个类的相关定义信息?这里大胆推测一下。
到这里我们知识分析完了
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();}
中的this()
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
中的
this.reader = new AnnotatedBeanDefinitionReader(this);
大概知道了spring会实例化一个DefaultListableBeanFactory对象在GenericApplicationContext(AnnotationConfigApplicationContext继承的类)中,然后把一些后处理器注册到DefaultListableBeanFactory中的beanDefinitionMap中,key为bean名称,值为BeanDefinition,虽然不知到干啥的,目前跟我们的目的,也就是找到什么地方去解析配置类没有任何关系的感觉,只不过可以推测因为配置类的@Configuration里面包含@Component,也会被实例化的,所以最后很可能也会放到DefaultListableBeanFactory中的beanDefinitionMap中。
我们继续跟踪
this.scanner = new ClassPathBeanDefinitionScanner(this);
代码,按字面意思是类路径下的BeanDefinition扫描器?难道是用来帮忙扫描@ComponentScan(basePackages = “com.suibibk.spring”)的工具类?
跟进去看看
/*** Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory.* @param registry the {@code BeanFactory} to load bean definitions into, in the form* of a {@code BeanDefinitionRegistry}*/public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {this(registry, true);}
创建一个新的ClassPathBeanDefinitionScanner对于bean工厂。这里的bean工厂应该就是DefaultListableBeanFactory,跟进去看看
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {this(registry, useDefaultFilters, getOrCreateEnvironment(registry));}
继续
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment) {this(registry, useDefaultFilters, environment,(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;if (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);}
就是设置一下环境,资源加载器什么的,感觉也不太理解,这里也不用去考虑又什么用先。
到这里this()方法就走完了,这里总结下主要内容
1、初始化了AnnotationConfigApplicationContext对象
2、初始化了AnnotationConfigApplicationContext的父对象GenericApplicationContext
3、GenericApplicationContext对象里面初始化了一个beanFactory成员变量,对象为DefaultListableBeanFactory
4.初始化了一个reader:AnnotatedBeanDefinitionReader
5、初始化reder的过程中把几个后置处理器比如internalPersistenceAnnotationProcessor和internalAutowiredAnnotationProcessor等放到了DefaultListableBeanFactory中的beanDefinitionMap中,key为bean的名称,值为beanDefinition放的应该是这些后置处理器的相关类定义
6.初始化了一个scanner:ClassPathBeanDefinitionScanner
推测所有要加载为bean的类都将放到beanDefinitionMap中!
好了,先到这里!
