前言
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器。
Demo:
配置类
/**
* @Author: klm
* @Date: 2020/11/6 23:46
* @Description:
*/
@Configuration
@ComponentScan("com.dream.sunny")
public class SunnyConfig {
}
Bean: SunnyEntity
/**
* @Author: klm
* @Date: 2020/11/7 23:30
* @Description:
*/
@Component
public class SunnyEntity {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SunnyEntity{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
启动类
/**
* @Author: klm
* @Date: 2020/11/7 23:49
* @Description:
*/
public class MyStart {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SunnyConfig.class);
UserServiceImpl bean = context.getBean(UserServiceImpl.class);
bean.sayHi();
SunnyEntity sunnyEntity = (SunnyEntity) context.getBean("sunnyEntity");
System.out.println(sunnyEntity);
}
}
Spring IOC加载流程分析开始
1.实例化AnnotationConfigApplicationContext容器
我们先从 AnnotationConfigApplicationContext 出发
ApplicationContext context = new AnnotationConfigApplicationContext(SunnyConfig.class);
我们先看一下AnnotationConfigApplicationContext 的类图关系
看完它的类图后,我们跟进它的构造方法中去
/**
* 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():调用本身构造函数,但是如果有父类的话,会先走父类的构造函数,再走子类的构造函数
this();
//注册配置类(将配置类注册到Bean定义中)
register(componentClasses);
//IOC容器刷新接口
refresh();
}
我们先对这个构造方法做一个简单的了解
1.从该构造方法的传入参数可以得知,我们可以传入很多个配置类,当然不过一般情况下,只会传入一个配置类
2.当然这个配置有两种说法
a.如果给配置类加了@Configurtion注解,那么在Sping容器里面会默认它为Full配置类
b.如果没有给配置类加@Configurtion注解,那么在Spring容器里面则认为它是Lite类,有些地方也把Lite类称之为普通Bean
2.初始化Bean工厂
接着我们进入this()来调用本类的无参构造方法
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
//类路径下Bean定义扫描器
private final ClassPathBeanDefinitionScanner scanner;
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
//这里继承了GenericApplicationContext类,在走本身的构造方法之前,会先走父类的构造方法
//从单词字面意思理解就是:创建一个注解的Bean定义读取器
//什么是Bean定义? BeanDefinition
// 就是定义Bean的规范,以便后面的Bean注册 (完成了spring内部BeanDefinition的注册(主要是后置处理器))
//
// 读取所有配置类
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 定义Bean扫描(其实就是扫描包的地方)
*
* 创建BeanDefinition扫描器
* 可以用来扫描包或者类,继而转换为Bean定义
*
* spring默认的扫描包不是这个scanner对象
* 而是自己new的一个ClassPathBeanDefinitionScanner
* spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
*
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
*
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
AnnotationConfigApplicationContext类是有继承关系的,会隐式调用父类的构造方法。
执行它无参构造方法,会先执行父类的构造方法,也就是先跳到GenericApplicationContext类,执行它的无参构造方法,然后初始化BeanFactory容器,因为该容器是生产我们的Bean对象的,所以必须在初始化的时候加载
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
@Nullable
private ResourceLoader resourceLoader;
private boolean customClassLoader = false;
private final AtomicBoolean refreshed = new AtomicBoolean();
/**
* Create a new GenericApplicationContext.
*
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
//为ApplicationContext上下文 初始化BeanFactory对象(实例化Bean工厂)
//可能会觉得有点疑惑,为啥是DefaultListableBeanFactory,因为这个是子类啊,最底层的实现,子类继承了父类的所有方法呢,所以更加强大呢
//可以查看DefaultListableBeanFactory它的类图即可明白
this.beanFactory = new DefaultListableBeanFactory();
}
}
那么可能有疑问,为什么是new DefaultListableBeanFactory() 而 不是直接使用BeanFactory接口?
我们来看下DefaultListableBeanFactory它的类图就明白了
1.我们可以看到BeanFactory它是一个顶层的接口,下面还有很多其他的工厂实现顶层工厂并进行增强, 但是通过类图得知DefaultListableBeanFactory实现了BeanFactory以及它的子工厂的所有功能,所以更加的强大,且拥有生产Bean的能力
2.并且它实现了BeanDefinitionRegistry接口,该接口的作用就是能够注册Bean定义,而实现了它,DefaultListableBeanFactory也拥有了注册Bean定义的功能
所以这就是为什么,在初始化BeanFactory用的是DefaultListableBeanFactory方法了
3.初始化Bean定义读取器
接着我们回到AnnotationConfigApplicationContext类中的this()方法
看到如下代码
this.reader = new AnnotatedBeanDefinitionReader(this);
该行代码主要做了两个事情
1.注册内置BeanPostProcessor
2.注册相关的BeanDefinition
我们跟进AnnotatedBeanDefinitionReader方法,来看看Spring初始化读取都做了些什么
这里的BeanDefinitionRegistry当然就是AnnotationConfigApplicationContext的实例了,这里又直接调用了此类其他的构造方法
/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
* the {@link Environment} will be inherited, otherwise a new
* {@link StandardEnvironment} will be created and used.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
* @see #setEnvironment(Environment)
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
让我们把目光移动到这个方法的最后一行,进入registerAnnotationConfigProcessors方法
/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry,
* using the given {@link Environment}.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @param environment the {@code Environment} to use when evaluating bean definition
* profiles.
* @since 3.1
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
this.registry = registry;
//用户处理条件注解 @Conditional os.name
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册一些内置的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
这又是一个门面方法,再点进去
/**
* 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);
}
registerAnnotationConfigProcessors这个方法的返回值Set,但是上游方法并没有去接收这个返回值,所以这个方法的返回值也不是很重要了,当然方法内部给这个返回值赋值也不重要了。
由于这个方法内容比较多,这里就把最核心的贴出来,这个方法的核心就是注册Spring内置的多个Bean
/**
* 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 registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//注册了实现Order接口的排序器
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//设置@AutoWired的候选的解析器:ContextAnnotationAutowireCandidateResolver
// getLazyResolutionProxyIfNecessary方法,它也是唯一实现。
//如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set beanDefs = new LinkedHashSet<>(8);
/**
* 值:名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* 这个if判断 其实就是将读取到的所有配置类进行解析成Bean定义 然后注册到 BeanDefinitionFactoryMap容器中
*/
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));
}
/**
* 为我们容器中注册了处理@Autowired 注解的处理器AutowiredAnnotationBeanPostProcessor
* 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
*/
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));
}
return beanDefs;
}
我们来详细分析如下代码
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));
}
1.判断容器中是否存在了 ConfigurationClassPostProcessor Bean
2.如果不存在(当然这里肯定不存在,因为在初始化阶段嘛),然后通过RootBeanDefinition的构造方法获得ConfigurationClassPostProcessor的BeanDedefinition(RootBeanDefinition是BeanDefinition的子类)
3.执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册其他Bean也是一样的流程。
ConfigurationClassPostProcessor类还有个重要的细节点就是 读取我们的配置类并解析 然后注册成Bean定义
这也就是为什么这个类能够解析@componentScan、@ComponentScans以及@import注解的原因啦
(可能会有疑问?为什么要实现BeanFacotryPostProcessor接口,才能进行解析这些注解? 因为该接口非常的灵活,且扩展性很高 BeanFactoryPostProcessor是实现spring容器功能扩展的重要接口,例如修改bean属性值,实现bean动态代理等。很多框架都是通过此接口实现对spring容器的扩展,例如mybatis与spring集成时 )
BeanDefinition是什么?
我们来看看BeanDefinition的类图
向上类图
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
AttributeAccessor接口:提供对BeanDefinition属性操作能力
向下类图
它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道。
然后我们跟进registerPostProcessor()方法
这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定义的
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()方法,跟进去
发现这个方法是接口里面的,没办法直接点进去,因为接口下实现了很多个方法,首先要知道registry实现类是什么,那么它的实现是什么呢?
答案是:DefaultListableBeanFactory
@Override
public 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_INFRASTRUCTURE
if (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 updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
} else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
} else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
看到这么多代码,估计大家伙有点晕了,问题不大,我们只关注里面的两行代码即可
//beanDefinitionMap是Map,
//这里就是把beanName作为key,ScopedProxyMode作为value,推到map里面
this.beanDefinitionMap.put(beanName, beanDefinition);
//beanDefinitionNames就是一个List,这里就是把beanName放到List中去
this.beanDefinitionNames.add(beanName);
从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,为什么这么说呢?因为我们跟进去这个方法就是在DefaultListableBeanFactory类中嘛
该类中里面放着全局静态变量beanDefinitionMap,beanDefinitionNames,beanDefinitionMap 他们都是一个ConcurrentHashMap
beanName作为Key,beanDefinition作为Value,beanDefinitionNames是一个集合,里面存放了beanName。
DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是相当重要的,以后会经常看到它,最好看到它,第一时间就可以反应出它里面放了什么数据
上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)就是BeanDefinitionRegistryPostProcessor Bean。
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类,必须牢牢的记住上面所说的这个类和它的继承关系。
除了注册了ConfigurationClassPostProcessor,还注册了其他Bean,其他Bean也都实现了其他接口,比如BeanPostProcessor等。
BeanPostProcessor接口也是Spring的扩展点之一。
至此,实例化AnnotatedBeanDefinitionReader reader分析完毕。
4.初始化Bean定义扫描器
接着我们回到AnnotationConfigApplicationContext类中的this()方法
看到如下代码
this.scanner = new ClassPathBeanDefinitionScanner(this);
由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法。所以这里就不看scanner是如何被实例化的了。
到这里我们前面的this方法就基本走完了,那大概总结一下this()方法主要实现了那几个步骤 1.初始化BeanFactory:主要实现两个接口,第一个 实现了Bean定义注册,第二个实现了初始化BeanFacotry 2.实例化Bean读取器:在Bean读取器底层会创建很多初始化类,如果不创建这些初始化的类并注册到Bean容器中,那么后面的普通的Bean对象也就无法加载到Spring容器中了 3.实例化Bean扫描器:这里主要扫描某些包下的所有类(例如:@componentScan("扫描包地址"))
5.注册配置类为BeanDefinition
总结完成后,我们回到AnnotationConfigApplicationContext类的的构造方法,接着我们在看到Registry()方法
//注册配置类(将配置类注册到Bean定义中)
register(componentClasses);
我们可以看到传入的参数是可以多个的,也就意味着我们可以传入多个的配置类,但是一般情况下,都是只会传入一个配置类的哈
@Override
public void register(Class>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
我们在跟进this.reader.register()方法
我们可以看到,它这里循环遍历我们传入的配置类,将我们所有传入的配置类注册成Bean定义
public void register(Class>... componentClasses) {
for (Class> componentClass : componentClasses) {
registerBean(componentClass);
}
}
继续跟进去registerBean()方法
public void registerBean(Class> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
我们来看一下doRegisterBean()注册方法
private void doRegisterBean(Class beanClass, @Nullable String name,
@Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//存储@Configuration注解注释的类
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//获得beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
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);
//注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
//DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
//beanDefinitionNames是一个List,用来保存beanName
//beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
1.通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过AnnotatedGenericBeanDefinition去获得。
2.判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的注册。
3.然后是解析作用域,如果没有设置的话,默认为单例。
4.获得BeanName。
5.解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description。
6.限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性)。
7.把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,可以简单的理解为方便传参)。
8.注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册
接着我们看到最后一行,跟进去
这个registerBeanDefinition是不是又有一种似曾相似的感觉,没错,在上面注册Spring内置的Bean的时候,已经解析过这个方法了,这里就不重复了,
如果此时是debug模式下的话,可以观察下beanDefinitionMap beanDefinitionNames两个静态变量的内容,集合中除了Spring内置的Bean,还有我们传进来的Bean,这里的Bean当然就是我们的配置类了
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
//获取beanName
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//注册bean
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
//Spring支持别名
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
到这里注册配置类也分析完毕了。
总结:这个方法的主要作用就是 将扫描到的配置类注册成Bean定义,这里仅仅只是注册扫描到的配置类哦~
6. refresh() Bean的生命周期
好啦,总结完成注册方法后,我们继续回到AnnotationConfigApplicationContext类的的构造方法,接着我们在看到本文最重要的一块refresh()方法了
//IOC容器刷新接口
refresh();
其实文章开始到这里,整个前面流程都只是将一些创世纪的类和我们的配置类注册成Bean定义,且Spring并没有去帮我们去实例化这些已经成为Bean定义的Bean
所以接下来分析的refresh()方法,就是来帮你干完剩下来的事情
我们来进入refresh()
refresh()的总体流程如下。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1.做些refresh前的准备工作、例如设置启动时间等
prepareRefresh();
//2:重点,刷新beanfactory,配置BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3:对bean工厂进行填充属性
prepareBeanFactory(beanFactory);
try {
// 4:拓展点,由自定义的context去实现,在BeanFactory准备工作完成后做一些定制化的处理
postProcessBeanFactory(beanFactory);
// 5.调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用
//BeanFactoryPostProcessors (解析配置类)
invokeBeanFactoryPostProcessors(beanFactory);
// 6.注册我们bean的后置处理器
registerBeanPostProcessors(beanFactory);
// 7.初始化国际化资源处理器.
initMessageSource();
// 8.创建事件多播器
initApplicationEventMulticaster();
// 9.这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
onRefresh();
//10.把我们的事件监听器注册到多播器上
registerListeners();
// 11.实例化剩余的单实例Bean (循环所有的Bean定义,将Bean注册到IOC容器中) 底层实现了getBean方法,实例化Bean对象
finishBeanFactoryInitialization(beanFactory);
// 12.最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
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.invokeBeanFactoryPostProcessors()
2.finishBeanFactoryInitialization()
把上述代码的关键流程使用流程图画出来,如图所示:
6.1 prepareRefresh()
从命名来看,就知道这个方法主要做了一些刷新前的准备工作,和主流程关系不大,主要是保存了容器的启动时间,启动标志等。
protected void prepareRefresh() {
//记录一下启动时间,是一个时间戳
this.startupDate = System.currentTimeMillis();
//将applicationContext状态设置非关闭
this.closed.set(false);
//将applicationContext状态设置已激活
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
//这个是留给子类去实现的,目前没做任何操作
initPropertySources();
//这里做了2个工作,一个是创建一个环境对象StandardEnvironment,另一个是校验必须的属性是否在环境变量中存在,不存在就抛异常MissingRequiredPropertiesException
getEnvironment().validateRequiredProperties();
//会尽量这里,默认是空
if (this.earlyApplicationListeners == null) {
//applicationListeners 为空集合
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
//清空applicationListeners集合内容
this.applicationListeners.clear();
//重新设置applicationListeners集合内容
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//收集早期的事件,一旦事件派发器可以使用,就派发这些事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}
6.2 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
这个方法和主流程关系也不是很大,可以简单的认为,就是把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition
这里有点深,就不贴代码了
6.3 prepareBeanFactory()
该方法的作用在于对Bean工厂进行初始化或者说给Bean工厂填充属性
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置类加载器,表达式解析器,资源相关的处理器
beanFactory.setBeanClassLoader(getClassLoader());
//设置bean表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//属性编辑器支持
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口
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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加一个后置处理器:ApplicationListenerDetector,此后置处理器实现了BeanPostProcessor接口,用于检测内部的的ApplicationListener
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 这个是用于类加载阶段进行AOP切入,而我们平时用的cglib或jdk动态代理是运行期切入
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()));
}
// 向容器中注册了3个环境相关的bean
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());
}
}
6.4 postProcessBeanFactory()
该方法是个空方法,可能以后Spring会对其进行扩展吧
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
6.5 invokeBeanFactoryPostProcessors()
调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 获取两处存储BeanFactoryPostProcessor的对象 传入供接下来的调用
// 1.当前Bean工厂
// 2.自定义BeanFactoryPostProcessor
// getBeanFactoryPostProcessors()方法是真的坑,刚开始一直以为这个地方永远都是空集合
// 到后面才知道,我们可以自己调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(x)添加bean工厂后置处理器
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()));
}
}
让我们来进入第一个方法的第二个参数 getBeanFactoryPostProcessors()方法
这个方法看单词的就知道是获取Bean工厂后置处理器嘛,看到此处,我当时就有点懵逼,既然是要获取bean的后置处理器,这他喵咋直接获取的一个空集合捏。
也没有找到地方入口将值插入,后来才知道可以在外部手动添加后置处理器,而不是由Spring容器去扫描获取
public List getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
//当点击this.beanFactoryPostProcessors,直接找到的是下面这行代码的空集合了。
private final List beanFactoryPostProcessors = new ArrayList<>();
接着回到上面代码,我们进入invokeBeanFactoryPostProcessors()方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
//调用BeanDefinitionRegistryPostProcessor的后置处理器 Begin
// 定义已处理的后置处理器
Set processedBeans = new HashSet<>();
//判断我们的beanFactory实现了BeanDefinitionRegistry 这里肯定进入if的
//因为beanFactory是DefaultListableBeanFactory类嘛(不要被参数误导,刚开始初始化beanFactory就是这个类哦),DefaultListableBeanFactory类他是实现了BeanDefinitionRegistry接口的
if (beanFactory instanceof BeanDefinitionRegistry) {
//强行把我们的bean工厂转为BeanDefinitionRegistry,因为待会需要注册Bean定义
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//保存BeanFactoryPostProcessor类型的后置处理器(普通后置处理器) --> BeanFactoryPostProcessor 提供修改
List regularPostProcessors = new ArrayList<>();
//保存BeanDefinitionRegistryPostProcessor类型的后置处理器(Bean定义注册后置处理器) --> BeanDefinitionRegistryPostProcessor 提供注册
List registryProcessors = new ArrayList<>();
// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
// 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
// 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor
// 扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor
// 是的话,直接执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//进行强制转化
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用他作为BeanDefinitionRegistryPostProcessor的处理器的后置方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中
registryProcessors.add(registryProcessor);
}
else {//若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
//把当前的后置处理器加入到普通后置处理器集合中
regularPostProcessors.add(postProcessor);
}
}
//定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
List currentRegistryProcessors = new ArrayList<>();
//第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环筛选出来的匹配BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//判断是否实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
//获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors
//ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口
//BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口
//ConfigurationClassPostProcessor是极其重要的类
//里面执行了扫描Bean,Import,ImportResouce等各种操作
//用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了
processedBeans.add(ppName);
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 把当前的加入到总的里面去
registryProcessors.addAll(currentRegistryProcessors);
// 执行 bean 定义注册器后置处理器,它会把 bean 定义注册器中的 bean 定义注册到 bean 工厂去
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//调用完之后,清空当前bean 定义注册器处理器列表
currentRegistryProcessors.clear();
//---------------------------------------调用内置实现PriorityOrdered接口ConfigurationClassPostProcessor完毕--优先级No1-End----------------------------------------------------------------------------------------------------------------------------
//去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称(内置的和上面注册的)
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//表示没有被处理过,且实现了Ordered接口的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
//调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//调用完之后,马上clea掉
currentRegistryProcessors.clear();
//-----------------------------------------调用自定义Order接口BeanDefinitionRegistryPostProcessor完毕-优先级No2-End-----------------------------------------------------------------------------------------------------------------------------
//调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
//定义一个重复处理的开关变量 默认值为true
boolean reiterate = true;
//第一次就可以进来
while (reiterate) {
//进入循环马上把开关变量给改为false
reiterate = false;
//去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//没有被处理过的
if (!processedBeans.contains(ppName)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
//再次设置为true
reiterate = true;
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
//调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//进行clear
currentRegistryProcessors.clear();
}
//-----------------------------------------调用没有实现任何优先级接口自定义BeanDefinitionRegistryPostProcessor完毕--End-----------------------------------------------------------------------------------------------------------------------------
//调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//调用BeanFactoryPostProcessor 自设的(没有)
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//若当前的beanFactory没有实现了BeanDefinitionRegistry 说明没有注册Bean定义的能力
// 那么就直接调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//-----------------------------------------所有BeanDefinitionRegistryPostProcessor调用完毕--End-----------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------处理BeanFactoryPostProcessor --Begin-----------------------------------------------------------------------------------------------------------------------------
//获取容器中所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//保存实现了priorityOrdered接口的BeanFactoryPostProcessor
List priorityOrderedPostProcessors = new ArrayList<>();
//保存实现了Ordered接口的BeanFactoryPostProcessor
List orderedPostProcessorNames = new ArrayList<>();
//保存BeanFactoryPostProcessor没有实现任何优先级接口的 (也就是保存剩下的Bean工厂后置处理器)
List nonOrderedPostProcessorNames = new ArrayList<>();
// 过滤掉已经处理过的后置处理器处理器,因为上面已经处理过了一些了
for (String ppName : postProcessorNames) {
//processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//判断是否实现了PriorityOrdered 优先级最高
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//判断是否实现了Ordered 优先级 其次
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//没有实现任何的优先级接口的 最后调用
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//调用实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 执行 bean 工厂的后置处理
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//调用实现了 Ordered 接口的 BeanFactoryPostProcessor
List orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 执行 bean 工厂的后置处理
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//调用没有实现任何方法接口的
List nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 执行 bean 工厂的后置处理
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//-----------------------------------------处理BeanFactoryPostProcessor --End-----------------------------------------------------------------------------------------------------------------------------
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
//------------------------- BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor调用完毕 --End-----------------------------------------------------------------------------------------------------------------------------
}
首先判断beanFactory是不是BeanDefinitionRegistry的实例,当然肯定是的,然后执行如下操作:
1.定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了。
2.定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor,一个是registryProcessors用来装载BeanDefinitionRegistryPostProcessor,其中BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor。BeanDefinitionRegistryPostProcessor有两个方法,一个是独有的postProcessBeanDefinitionRegistry方法,一个是父类的postProcessBeanFactory方法。
3.循环传进来的beanFactoryPostProcessors,上面已经解释过了,一般情况下,这里永远都是空的,只有手动add beanFactoryPostProcessor,这里才会有数据。我们假设beanFactoryPostProcessors有数据,进入循环,判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor,是的话,执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去,不是的话,就装到regularPostProcessors。
4.定义了一个临时变量:currentRegistryProcessors,用来装载BeanDefinitionRegistryPostProcessor。
5.getBeanNamesForType,顾名思义,是根据类型查到BeanNames,这里有一点需要注意,就是去哪里找,点开这个方法的话,就知道是循环beanDefinitionNames去找,这个方法以后也会经常看到。这里传了BeanDefinitionRegistryPostProcessor.class,就是找到类型为BeanDefinitionRegistryPostProcessor的后置处理器,并且赋值给postProcessorNames。一般情况下,只会找到一个,就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,也就是ConfigurationAnnotationProcessor。这个后置处理器在上一节中已经说明过了,十分重要。这里有一个问题,为什么我自己写了个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步,Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个invokeBeanDefinitionRegistryPostProcessors方法。
6.循环postProcessorNames,其实也就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,判断此后置处理器是否实现了PriorityOrdered接口(ConfigurationAnnotationProcessor也实现了PriorityOrdered接口),
如果实现了,把它添加到currentRegistryProcessors这个临时变量中,再放入processedBeans,代表这个后置处理已经被处理过了。当然现在还没有处理,但是马上就要处理了。。。
7.进行排序,PriorityOrdered是一个排序接口,如果实现了它,就说明此后置处理器是有顺序的,所以需要排序。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
8.把currentRegistryProcessors合并到registryProcessors,为什么需要合并?因为一开始spring只会执行BeanDefinitionRegistryPostProcessor独有的方法,而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor接口中的方法,所以需要把这些后置处理器放入一个集合中,后续统一执行BeanFactoryProcessor接口中的方法。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
9.可以理解为执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法,这就是Spring设计思想的体现了,在这里体现的就是其中的热插拔,插件化开发的思想。Spring中很多东西都是交给插件去处理的,这个后置处理器就相当于一个插件,如果不想用了,直接不添加就是了。这个方法特别重要,我们后面会详细说来。
10.清空currentRegistryProcessors,因为currentRegistryProcessors是一个临时变量,已经完成了目前的使命,所以需要清空,当然后面还会用到。
11.再次根据BeanDefinitionRegistryPostProcessor获得BeanName,然后进行循环,看这个后置处理器是否被执行过了,如果没有被执行过,也实现了Ordered接口的话,把此后置处理器推送到currentRegistryProcessors和processedBeans中。
这里就可以获得我们定义的,并且打上@Component注解的后置处理器了,因为Spring已经完成了扫描,但是这里需要注意的是,由于ConfigurationClassPostProcessor在上面已经被执行过了,所以虽然可以通过getBeanNamesForType获得,但是并不会加入到currentRegistryProcessors和processedBeans。
12.处理排序。
13.合并Processors,合并的理由和上面是一样的。
14.执行我们自定义的BeanDefinitionRegistryPostProcessor。
15.清空临时变量。
16.在上面的方法中,仅仅是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,这里是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor。
17.上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次。
18.执行regularPostProcessors中的后置处理器的方法,需要注意的是,在一般情况下,regularPostProcessors是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据。
19.查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。和上面的逻辑差不多,不再详细说明。
这就是这个方法中做的主要的事情了,可以说是比较复杂的。
我们来看看invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);这行代码
跟入进去,可以看到它是实现了多个方法,我们主要看的是ConfigurationClassPostProcessor
我们的重点是看到最后一行processConfigBeanDefinitions()方法,解析我们的bean定义,跟入进去
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//真正的解析我们的bean定义
processConfigBeanDefinitions(registry);
}
进入解析Bean定义的方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List configCandidates = new ArrayList<>();
//获取IOC 容器中目前所有bean定义的名称
String[] candidateNames = registry.getBeanDefinitionNames();
//循环我们的上一步获取的所有的bean定义信息
for (String beanName : candidateNames) {
//通过bean的名称来获取我们的bean定义对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断是否有没有解析过
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//满足添加 就加入到候选的配置类集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 若没有找到配置类 直接返回
if (configCandidates.isEmpty()) {
return;
}
//对我们的配置类进行Order排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 创建我们通过@CompentScan导入进来的bean name的生成器
// 创建我们通过@Import导入进来的bean的名称
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
//设置@CompentScan导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
this.componentScanBeanNameGenerator = generator;
//设置@Import导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//创建一个配置类解析器对象
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//用于保存我们的配置类BeanDefinitionHolder放入上面筛选出来的配置类
Set candidates = new LinkedHashSet<>(configCandidates);
//用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
Set alreadyParsed = new HashSet<>(configCandidates.size());
//do while 会进行第一次解析
do {
//真正的解析我们的配置类
parser.parse(candidates);
parser.validate();
//解析出来的配置类
Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 此处才把@Bean的方法和@Import 注册到BeanDefinitionMap中
this.reader.loadBeanDefinitions(configClasses);
//加入到已经解析的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
//判断我们ioc容器中的是不是>候选原始的bean定义的个数
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取所有的bean定义
String[] newCandidateNames = registry.getBeanDefinitionNames();
//原始的老的候选的bean定义
Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set alreadyParsedClasses = new HashSet<>();
//赋值已经解析的
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
//表示当前循环的还没有被解析过
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
//判断有没有被解析过
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
//存在没有解析过的 需要循环解析
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
1.获得所有的BeanName,放入candidateNames数组。
2.循环candidateNames数组,根据beanName获得BeanDefinition,判断此BeanDefinition是否已经被处理过了。
3.判断是否是配置类,如果是的话。加入到configCandidates数组,在判断的时候,还会标记配置类属于Full配置类,还是Lite配置类,这里会引发一连串的知识盲点:
3.1 当我们注册配置类的时候,可以不加@Configuration注解,直接使用@Component @ComponentScan @Import @ImportResource等注解,Spring把这种配置类称之为Lite配置类, 如果加了@Configuration注解,就称之为Full配置类。
3.2 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类,如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了。
3.3 写一个A类,其中有一个构造方法,打印出“你好”,再写一个配置类,里面有两个被@bean注解的方法,其中一个方法new了A类,并且返回A的对象,把此方法称之为getA,第二个方法又调用了getA方法,如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次,如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写。
4.如果没有配置类直接返回。
5.处理排序。
6.解析配置类,可能是Full配置类,也有可能是Lite配置类,这个小方法是此方法的核心,稍后具体说明。
7.在第6步的时候,只是注册了部分Bean,像 @Import @Bean等,是没有被注册的,这里统一对这些进行注册。
下面是解析配置类的过程
public void parse(Set configCandidates) {
//循环传进来的配置类
for (BeanDefinitionHolder holder : configCandidates) {
//获得BeanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
//如果获得BeanDefinition是AnnotatedBeanDefinition的实例
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
this.deferredImportSelectorHandler.process();
}
6.6 registerBeanPostProcessors()
实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
例如:
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//去容器中获取所有的BeanPostProcessor 的名称(还是bean定义)
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
/**
* bean的后置处理器的个数 beanFactory.getBeanPostProcessorCount()成品的个数 之前refresh-->prepareBeanFactory()中注册的
* postProcessorNames.length beanFactory工厂中bean定义的个数
* +1 在后面又马上注册了BeanPostProcessorChecker的后置处理器
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
/**
* 按照BeanPostProcessor实现的优先级接口来分离我们的后置处理器
*/
//保存实现了priorityOrdered接口的
List priorityOrderedPostProcessors = new ArrayList<>();
//系统内部的
List internalPostProcessors = new ArrayList<>();
//实现了我们ordered接口的
List orderedPostProcessorNames = new ArrayList<>();
//没有优先级的
List nonOrderedPostProcessorNames = new ArrayList<>();
//循环我们的bean定义(BeanPostProcessor)
for (String ppName : postProcessorNames) {
//若实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//显示的调用getBean流程创建bean的后置处理器
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//加入到集合中
priorityOrderedPostProcessors.add(pp);
//判断是否实现了MergedBeanDefinitionPostProcessor
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//加入到集合中
internalPostProcessors.add(pp);
}
}
//判断是否实现了Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//没有任何拍下接口的
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 把实现了priorityOrdered注册到容器中
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 处理实现Ordered的bean定义
List orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
//显示调用getBean方法
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//加入到集合中
orderedPostProcessors.add(pp);
//判断是否实现了MergedBeanDefinitionPostProcessor
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//加入到集合中
internalPostProcessors.add(pp);
}
}
//排序并且注册我们实现了Order接口的后置处理器
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 实例化我们所有的非排序接口的
List nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
//显示调用
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
//判断是否实现了MergedBeanDefinitionPostProcessor
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册我们普通的没有实现任何排序接口的
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//注册.MergedBeanDefinitionPostProcessor类型的后置处理器 bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析。
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//注册ApplicationListenerDetector 应用监听器探测器的后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
6.7 initMessageSource()
初始化国际化资源处理器 (不是主线代码,没啥学习价值,可以直接忽略)
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//先判断容器中有没对应的bean
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
//设置父容器的MessageSource
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
} else {
//容器中不存在,就新创建一个,然再将其放到ioc中
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
6.8 initApplicationEventMulticaster()
初始化事件派发器,该对象存有一个list,值的内容是监听器,里面还有个发布事件的方法,发布事件时,遍历监听器,调用每个监听器去处理该事件
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//容器中已存在就直接获取
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
//容器中不存在就创建
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
6.9 onRefresh()
这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的,且它是一个模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
6.10 registerListeners()
把我们的事件监听器注册到多播器上,然后派发事件
protected void registerListeners() {
// 容器中已存在就直接获取
for (ApplicationListener> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 容器中不存在就创建
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
6.11 finishBeanFactoryInitialization()
实例化剩余的单实例Bean (循环所有的Bean定义,将Bean注册到IOC容器中) 底层实现了getBean方法,实例化Bean对象
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 为我们的bean工厂创建类型转化器 Convert
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 处理关于aspectj
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//getBean方法,就相当于实例化Bean对象了
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
//允许缓存所有bean定义元数据,而不期望进一步的更改
//冻结所有的Bean定义,说明注册的Bean定义将不被修改或任何进一步处理(可以理解为:Spring要进行生产Bean了,所以不允许外部再进行修改Bean)
beanFactory.freezeConfiguration();
//实例化剩余的单实例bean(这里指的剩余的Bean是被invokeBeanFactoryPostProcessors方法解析的@conponent注解的类嘛,直接解析成Bean定义了
// 但是还没有实例化,而那些创世纪的类,已经在invokeBeanFactoryPostProcessors方法实例化完成了)
beanFactory.preInstantiateSingletons();
}
在这个方法我们主要看两个步骤
1.beanFactory.freezeConfiguration(); 冻结所有的Bean定义
2.beanFactory.preInstantiateSingletons(); 开始实例化剩余的Bean
我们进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.freezeConfiguration()方法
我们进入方法中,其实就是只做了一件事情,就是将所有的Bean都设置为true,这样IOC容器在继续实例化Bean的时候,只要判断Bean是否为true即可
可能为有疑惑,为什么要冻结 因为 我们在实例化Bean(生产Bean)的过程中, 外部又需要进行修改Bean 所以就会进行判断该Bean的属性是否为true,如果为true说明在生产Bean,还不能够对Bean进行修改,只有等false了,才能继续修改哦
@Override
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
好,第一个步骤看完后,我们在接下来再来跟第二个步骤
我们再进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.preInstantiateSingletons()方法,也就是该方法的最后一行代码
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 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.
//获取我们容器中所有bean定义的名称
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
//循环我们所有的bean定义名称
for (String beanName : beanNames) {
//合并我们的bean定义,转换为统一的RootBeanDefinition类型(在), 方便后续处理
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/**
* 根据bean定义判断是不是抽象的&& 不是单例的 &&不是懒加载的
*/
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是否为工厂Bean
if (isFactoryBean(beanName)) {
// 是factoryBean会先生成实际的bean &beanName 是用来获取实际bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean> factory = (FactoryBean>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction) ((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
//调用真正的getBean的流程
if (isEagerInit) {
getBean(beanName);
}
}
} else {
//非工厂Bean,就是普通的Bean对象
getBean(beanName);
}
}
}
//或有的bean的名称 ...........到这里所有的单实例的bean已经记载到单实例bean到缓存中
for (String beanName : beanNames) {
//从单例缓存池中获取所有的对象
Object singletonInstance = getSingleton(beanName);
//判断当前的bean是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
首先会将beanDefinitionMap里面的所有的Bean的名称放在一个集合中,然后遍历集合里的Bean的名称
为什么是遍历Bean的名称,而不是遍历Bean实例呢?
是因为不同的注解注入的Bean是不统一的,例如@Component 和 @Bean 两种方法注册的Bean格式是不一样的,所以才会需要根据Bean的名称去遍历
然后我们在看到if判断 isFactoryBean(beanName) 的这个,判断它是否为工厂Bean,注意这里判断的工厂Bean
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
是判断该Bean是否实现了FactoryBean,如果没有实现则进入,调用我们的getBean进行真正的实例化Bean操作
如果是工厂Bean则进行特殊处理,然后进行实例化Bean操作
我们这里是没有实现的
所以进入普通Bean实例化,也就是进入方法,开始调用getBean()方法来进行实例化对象
我们跟进getBean底层方法,doGetBean()方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
在跟进去
protected T doGetBean(
String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/**
* 在这里 传入进来的name 可能是别名, 也有可能是工厂bean的name,所以在这里需要转换,获取最真实的Bean名称
*/
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//尝试去缓存中获取对象(从一级缓存获取数据)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* /*
*
* 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
* sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
* bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
* 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* spring 只能解决单例对象的setter 注入的循环依赖,不能解决构造器注入
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
/**
* 判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为abstractBeanFactory直接是抽象类,不存在父工厂)
* 一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念,
* 比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
* 但是当前所在的容器是web子容器,那么就会在这里的 先去父容器找
*/
BeanFactory parentBeanFactory = getParentBeanFactory();
//若存在父工厂,切当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFacotry中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取bean的原始名称
String nameToLookup = originalBeanName(name);
//若为 AbstractBeanFactory 类型,委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 委托给构造函数 getBean() 处理
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 没有 args,委托给标准的 getBean() 处理
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
/**
* 方法参数 typeCheckOnly ,是用来判断调用 #getBean(...) 方法时,表示是否为仅仅进行类型检查获取 Bean 对象
* 如果不是仅仅做类型检查,而是创建 Bean 对象,则需要调用 #markBeanAsCreated(String beanName) 方法,进行记录
*/
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
/**
* 从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
*
*/
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
/**
*
* @Bean
public DependsA dependsA() {
return new DependsA();
}
@Bean
@DependsOn(value = {"dependsA"})
public DependsB dependsB() {
return new DependsB();
}
* 处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
*/
//依赖bean的名称
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// <1> 若给定的依赖 bean 已经注册为依赖给定的 bean
// 即循环依赖的情况,抛出 BeanCreationException 异常
for (String dep : dependsOn) {
//beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
registerDependentBean(dep, beanName);
try {
//获取depentceOn的bean
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建单例bean
if (mbd.isSingleton()) {
//把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
sharedInstance = getSingleton(beanName, () -> {
try {
//进入创建bean的逻辑
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
//创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
看到这么多代码,莫慌,我们只看重点。
我们看到这里面的createBean方法,再点进去啊,但是又点不进去了,这是接口啊,但是别慌,这个接口又只有一个实现类,所以说 没事,就是干,这个实现类为org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。
这个实现的方法里面又做了很多事情,我们就不去看了,我就是带着大家找到那几个生命周期的回调到底定义在哪里就OK了。
if (mbd.isSingleton()) {
//getSingleton中的第二个参数类型是ObjectFactory>,是一个函数式接口,不会立刻执行,而是在
//getSingleton方法中,调用ObjectFactory的getObject,才会执行createBean
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
跟进去createBean方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确保此时的 bean 已经被解析了
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
/**
* 验证和准备覆盖方法( 仅在XML方式中)
* lookup-method 和 replace-method
* 这两个配置存放在 BeanDefinition 中的 methodOverrides( 仅在XML方式中)
* 在XML方式中 bean 实例化的过程中如果检测到存在 methodOverrides ,
* 则会动态地位为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
* 具体的实现我们后续分析,现在先看 mbdToUse.prepareMethodOverrides() 代码块
*/
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
/**
* 第1个bean后置处理器
* 通过bean的后置处理器来进行后置处理生成代理对象,一般情况下在此处不会生成代理对象
* 为什么不能生成代理对象,不管是我们的jdk代理还是cglib代理都不会在此处进行代理,因为我们的
* 真实的对象没有生成,所以在这里不会生成代理对象,那么在这一步是我们aop和事务的关键,因为在这里
* 解析我们的aop切面信息进行缓存
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
/**
* 该步骤是我们真正的创建我们的bean的实例对象的过程
*/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
莫慌,我们关注重点,看如下代码
Object beanInstance = doCreateBean(beanName, mbdToUse, args);//创建bean,核心
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
再继续深入doCreateBean方法,这个方法又做了一堆一堆的事情,但是值得开心的事情就是 我们已经找到了我们要寻找的东西了。
创建实例
首先是创建实例,位于:
instanceWrapper = createBeanInstance(beanName, mbd, args);//创建bean的实例。核心
填充属性
其次是填充属性,位于:
populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要
继续深入进去。
aware系列接口的回调
aware系列接口的回调位于initializeBean中的invokeAwareMethods方法:
invokeAwareMethods(beanName, bean);
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
BeanPostProcessor的postProcessBeforeInitialization方法
BeanPostProcessor的postProcessBeforeInitialization方法位于initializeBean的
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
afterPropertiesSet init-method
afterPropertiesSet init-method位于initializeBean中的
invokeInitMethods(beanName, wrappedBean, mbd);
这里面调用了两个方法,一个是afterPropertiesSet方法,一个是init-method方法:
((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);
BeanPostProcessor的postProcessAfterInitialization方法
BeanPostProcessor的postProcessAfterInitialization方法位于initializeBean的
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterI nitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
当然在实际的开发中,应该没人会去销毁Spring的应用上下文把,所以剩余的两个销毁的回调就不去找了。
6.12 finishRefresh()
最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
protected void finishRefresh() {
//1.清除缓存
clearResourceCaches();
//2.为此上下文初始化生命周期处理器
initLifecycleProcessor();
//3.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
getLifecycleProcessor().onRefresh();
// 4.推送上下文刷新完毕事件到相应的监听器
publishEvent(new ContextRefreshedEvent(this));
// 5.这个方法不清楚啥作用
LiveBeansView.registerApplicationContext(this);
}
到此本文的Spring IOC 加载流程源码分析完毕。