目录
4.5 invokeBeanFactoryPostProcessors()
4.6 registerBeanPostProcessors()
4.8 initApplicationEventMulticaster()
4.11 finishBeanFactoryInitialization(beanFactory)
一、IoC与DI
IoC(控制反转)就是把原来代码里需要实现的对象创建、依赖,反转给容器来帮忙实现。我们需要创建一个容器,同时需要一种描述来让容器知道要创建的对象和对象的关系。这个描述的最具体的表现就是我们看到的配置文件。
DI(Dependency Injection,依赖注入) 就是指对象被动接收依赖类而不自己主动去找,换句话说,就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象时主动将它依赖的类注入给它。
二、Spring核心容器类
Spring IoC 从代码层面来说,有3个核心的抽象类:
- ApplicationContext:应用上下文,即“容器”
- Bean:容器中的对象
- BeanFactory:bean工厂,使用工厂模式来生产bean。
ApplicationContext接口的实现类通过持有一个BeanFactory接口实例,来完成bean的自动装配工作,它们之间的抽象关系可以用下图来表示:
2.1 ApplicationContext
ApplicationContext接口是Spring容器的核心抽象,有多个实现子类,使用多结构继承,其具体实现子类中有3个常用的类:
ClassPathXmlApplicationContext:从classpath下加载bean的配置文件FileSystemXmlApplicationContext:从系统路径下加载bean的配置文件AnnotationConfigApplicationContext:基于注解的方式读取bean的配置
SpringBoot基于注解编程,管理注解的Bean定义的容器有两个: AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext。这两个是专门处理Spring注解方式配置的容器,直接依赖于将注解作为容器配置信息来源的IoC容器。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的Web版本,两者的用法以及对注解的处理方式几乎没有区别。AnnotationConfigWebApplicationContext的类继承结构如下图所示:
2.2 BeanFactory
Spring中Bean的创建是典型的工厂模式,这一系列的Bean工厂,为开发者管理对象之间的依赖关系提供了很多便利和基础服务,在Spring中有许多IoC容器的实现供用户选择,其类关系结构图如下:
其中,BeanFactory作为最顶层的一个接口类,定义了IoC容器的基本功能规范,BeanFactory有三个重要的子类:ListableBeanFactory、HierachicalBeanFactory和AutowireCapableBeanFactory。
2.3 Bean
Spring 将需要自动实例化的对象称为bean对象,使用了BeanDefinition抽象接口来描述bean对象:包括bean的名称,scope,是否懒加载等。在初始扫描包路径下的所有类时,会将类的信息放到Map<String, BeanDefinition> beanDefinitionMap 这个map中,其中key为bean的name。
三、基于注解的IoC初始化
IoC容器的初始化包括BeanDefinition的Resource定位、加载和注册3个基本的过程。在Spring2.0以后的版本中,引入了基于注解(Annotation)方式的配置,注解是JDK1.5引入的一个新特性,用于简化Bean的配置,可以取代XML配置文件。SpringIoC容器对于类级别的注解和类内部的注解处理策略如下:
1) 类级别的注解:如@Component,@Service, @Controller,都是添加在类上的类级别注解,Spring IoC容器根据注解的过滤规则扫描读取Bean定义类,并将其注册到Spring IoC容器中。
2) 类内部的注解:如@Autowire、@Value、@Resource,都是添加在类内部的字段或者方法上的类的类内部注解,Spring IoC容器通过Bean后置注解处理器解析Bean 内部的注解。
3.1 扫描及注册beandefinition
AnnotationConfigApplicationContext类里面有3个重要成员:
beanFactory:DefaultListableBeanFactory,位于父类GenericApplicationContext中,存放beandefinition以及负责生成bean对象。 reader:AnnotatedBeanDefinitionReader,根据传入的componentClasses参数扫描符合条件的类。 scanner:ClassPathBeanDefinitionScanner,根据传入的packagepath参数来扫描符合条件的类。
AnnotationConfigApplicationContext完成bean的装配过程就两个核心步骤:
1. 调用register() 或 scan() 方法完成类的扫描,将符合装配条件的类抽象出BeanDefinition,然后放入beanDefinitionMap中,其key为bean name,value为BeanDefinition实例类。
2. 调用refresh() 方法完成bean的装载。
register()方法扫描bean的最核心代码流程如下:
// 1. 构造AnnotatedGenericBeanDefinition对象,解析beanClass的元信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 2. 处理bean的scope,以及作用在bean上的@Primary,@Lazy注解:
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));
}
}
}
// 3. 向beanFactory注册beanDefinition
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
3.2 自动装配bean
bean的自动装配工作是在refresh()方法中完成的,该方法核心代码如下:
public void refresh() throws BeansException, IllegalStateException {
// 1. Prepare this context for refreshing.
prepareRefresh();
// 2. Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
// 4. Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 5. Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 6. Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 7. Initialize message source for this context.
initMessageSource();
// 8. Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9. Initialize other special beans in specific context subclasses.
onRefresh();
// 10. Check for listener beans and register them.
registerListeners();
// 11. Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 12. Last step: publish corresponding event.
finishRefresh();
}
四、refresh()方法源码解读
在分析Spring源码前,需要知道一些关键信息:
1. Spring 创建bean对象的核心流程为:1) 反射调用类的构造方法生成bean实例;2) 为bean对象依赖的属性赋值(自动注入依赖);3) 执行bean对象的init-method(如果有定义)
2. Spring 使用三级缓存来解决对象属性循环依赖的问题。其核心是思想是:假如类A和类B 存在循环依赖,先调用A类的构造方法产生beanA实例,然后放入到一个特殊的缓存中(还无法被直接使用),然后为beanA注入依赖属性,发现依赖B类的实例,会去调用B类的构造方法产生beanB实例,为beanB实例注入依赖属性,发现依赖A类,从这个特殊的缓存中取出A,将其赋值给beanB,完成beanB的属性注入及对象创建,最后将这个创建好的beanB对象赋值给beanA,完成beanA对象创建。
3. Spring 定义了BeanProcessor(后置处理器)接口,Sping在创建普通bean对象的阶段都会调用实现了该接口的bean类的回调方法,即如果存入一个BeanProcessor接口的实例类,如果创建n个普通bean对象,则该实例类的回调方法会被调用n次。BeanProcessor 非常重要,它提供了在创建bean的阶段,修改bean的属性及行为,或者返回一个bean的代理类的功能,它也是实现AOP的基础。
BeanFactory.getBean 方法
在分析具体流程源码前,应该先了解下 BeanFactory.getBean 方法, Spring使用该方法创建所有的bean对象,AbstractBeanFactory 实现了该方法,该方法的调用流程如下图所示:
主要流程为getBean() -> doGetBean() -> createBean() -> doCreateBean()。
4.1 prepareRefresh()
prepareRefresh()方法:刷新前的预处理,核心代码如下:
protected void prepareRefresh() {
// 初始化一些属性设置;子类自定义个性化的属性设置方法
initPropertySources();
// 检验属性的合法等
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// 保存容器中的一些早期的事件;
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
}
4.2 refreshBeanFactory()
refreshBeanFactory():刷新或者创建一个BeanFactory,默认的beanFactory实例对象在父类GenericApplicationContext的构造方法里面创建:
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
4.3 prepareBeanFactory()
prepareBeanFactory() :beanFactory的预准备工作,主要做了以下事情:
1)、设置BeanFactory的类加载器、支持表达式解析器...
2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)、添加BeanPostProcessor【ApplicationListenerDetector】
6)、给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map<String, Object>】、
systemEnvironment【Map<String, Object>】
该方法核心代码如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置bean的类加载器.
beanFactory.setBeanClassLoader(getClassLoader());
// 添加ApplicationContextAwareProcessor这个后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 提前注册一些依赖关系,即如果某些类依赖这些特殊的底层类时,可以直接返回这些对象
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加ApplicationListenerDetector 后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 注册默认的environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
4.4 postProcessBeanFactory()
postProcessBeanFactory(beanFactory):BeanFactory准备工作完成后进行的后置处理工作,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置,默认实现为空。
4.5 invokeBeanFactoryPostProcessors()
invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor的方法。BeanFactoryPostProcessor:BeanFactory后置处理器,是在beanFactory对象创建后调用。 BeanFactoryPostProcessor 还有一个子接口 BeanDefinitionRegistryPostProcessor,invokeBeanFactoryPostProcessors() 方法的调用流程可以分为两个阶段:
1. 先寻找到BeanDefinitionRegistryPostProcessor 接口的实现类,并执行其回调方法:
1)、获取所有的BeanDefinitionRegistryPostProcessor;
2)、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
postProcessor.postProcessBeanDefinitionRegistry(registry)
3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
postProcessor.postProcessBeanDefinitionRegistry(registry)
4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
postProcessor.postProcessBeanDefinitionRegistry(registry)
2. 然后再找到BeanFactoryPostProcessor接口的实现类(排除上面已经调用过的类),并执行其回调方法:
1)、获取所有的BeanFactoryPostProcessor
2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
postProcessor.postProcessBeanFactory()
3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
其中第一阶段的流程比较重要,它的核心代码如下图所示:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 获取BeanDefinitionRegistryPostProcessor接口的实现类的beanName,这里会获取到一个重要类ConfigurationClassPostProcessor,该类会去扫描使用了@Configuration注解的配置类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 调用beanFactory.getBean方法获得ConfigurationClassPostProcessor类实例
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用BeanDefinitionRegistryPostProcessor接口的实现类的回调方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
该方法先去获取所有的BeanDefinitionRegistryPostProcessor,会扫描到一个关键Bean对象:ConfigurationClassPostProcessor。这个类对BeanDefinitionRegistryPostProcessor接口的实现方法,主要任务是去扫描@Component,@ComponentSanc,@Import, @Configuration 等几个可能会引入新的bean定义的注解。
这个怎么理解呢,假设我现在有一个注解配置类:
@Configuration
@Import({JacksonAnnotationIntrospector.class})
public class AppConfig {
@Bean
public People getPeople() {
People people = new People();
people.setName("haha");
return people;
}
}
其@Import 和 @Bean 注解都是向容器中添加新的bean实例,而这些bean是没有在 register(bean扫描) 阶段被处理的。所以 ConfigurationClassPostProcessor 类需要扫描这些类,并将其扫苗到的新的bean的元信息添加到容器中。需要注意的是,此时 AppConfig 类以及@Import 引入的 JacksonAnnotationIntrospector 类的实例还是没有被加载,只是扫描了元信息。
另外,更重要的一点就是,ConfigurationClassPostProcessor 类会去处理@Enablexxx 注解,例如下面的注解配置类:
@EnableCaching
@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
@Bean("person")
public Person person01(){
return new Person("lisi", 20);
}
}
@Enablexxx 注解其核心都是里面有一个@Import注解,例如@EnableAspectJAutoProxy注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
}
ConfigurationClassParser 处理@EnableAspectJAutoProxy 里面的 @Import注解时,便会扫描到org.springframework.context.annotation.AspectJAutoProxyRegistrar类,该类是ImportBeanDefinitionRegistrar接口的实现类。在随后调用该类的registerBeanDefinitions() 方法时,会把一个重要的类 AnnotationAwareAspectJAutoProxyCreator 的元信息注册到beanFactory中。该类是 InstantiationAwareBeanPostProcessor 接口的实现类,是一个非常重要的BeanPostProcessor,是Spring 实现 aop 代理的核心类。
4.6 registerBeanPostProcessors()
BeanPostProcessor(Bean的后置处理器),实现了这些接口的实例类,beanFactory调用registerBeanPostProcessors 方法将其添加到自身的属性 List<BeanPostProcessor> beanPostProcessors 中,并在后面创建应用bean的阶段调用,BeanPostProcessor 的接口继承关系如下图所示(我已在图上标注了方法调用时机):
registerBeanPostProcessors() 方法执行流程如下:
1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
2)、先注册PriorityOrdered优先级接口的BeanPostProcessor;
把每一个BeanPostProcessor;添加到BeanFactory中
beanFactory.addBeanPostProcessor(postProcessor);
3)、再注册Ordered接口的
4)、最后注册没有实现任何优先级接口的
5)、最终注册MergedBeanDefinitionPostProcessor;
6)、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是
applicationContext.addApplicationListener((ApplicationListener<?>) bean);
4.7 initMessageSource()
initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析),流程如下:
1)、获取BeanFactory
2)、看容器中是否有id为messageSource的,类型是MessageSource的组件
如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
3)、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);
4.8 initApplicationEventMulticaster()
initApplicationEventMulticaster():初始化事件派发器:
1)、获取BeanFactory
2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
4.9 onRefresh()
onRefresh():留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑。
4.10 registerListeners()
registerListeners():给容器中将所有项目里面的ApplicationListener接口的实现类注册进来:
1、从容器中拿到所有的ApplicationListener
2、将每个监听器添加到事件派发器中;
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3、派发之前步骤产生的事件;
4.11 finishBeanFactoryInitialization(beanFactory)
finishBeanFactoryInitialization() 方法调用beanFactory.preInstantiateSingletons() 方法初始化所有剩下的单实例bean,该方法内容非常多,代码就不在这里贴出来了,有兴趣的同学可以debug代码,流程如下:
1)、获取容器中的所有Bean,依次进行初始化和创建对象
2)、获取Bean的定义信息;RootBeanDefinition
3)、Bean不是抽象的,是单实例的,是懒加载;
1)、判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
2)、不是工厂Bean。利用getBean(beanName) 创建对象
0、getBean(beanName); ioc.getBean();
1、doGetBean(name, null, null, false);
2、先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);获取的
3、缓存中获取不到,开始Bean的创建对象流程;
4、标记当前bean已经被创建
5、获取Bean的定义信息;
6、【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】
7、启动单实例Bean的创建流程;
1)、createBean(beanName, mbd, args);
2)、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象;
【InstantiationAwareBeanPostProcessor】:提前执行;
先触发:postProcessBeforeInstantiation();
如果有返回值:触发postProcessAfterInitialization();
3)、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)
4)、Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean
1)、【创建Bean实例】;createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出Bean实例;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
赋值之前:
1)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessAfterInstantiation();
2)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessPropertyValues();
=====赋值之前:===
3)、应用Bean属性的值;为属性利用setter方法等进行赋值;
applyPropertyValues(beanName, mbd, bw, pvs);
4)、【Bean初始化】initializeBean(beanName, exposedObject, mbd);
1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法
BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2)、【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
BeanPostProcessor.postProcessBeforeInitialization();
3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1)、是否是InitializingBean接口的实现;执行接口规定的初始化;
2)、是否自定义初始化方法;
4)、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization
BeanPostProcessor.postProcessAfterInitialization();
5)、注册Bean的销毁方法;
5)、将创建的Bean添加到缓存中singletonObjects;
ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。;
所有Bean都利用getBean创建完成以后;
检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
4.12 finishRefresh()
finishRefresh(),完成BeanFactory的初始化创建工作;IOC容器就创建完成,流程如下:
1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor() 加入到容器;
2)、getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
4)、liveBeansView.registerApplicationContext(this);