目录
一、IoC与DI
二、Spring核心容器类
2.1 ApplicationContext
2.2 BeanFactory
2.3 Bean
三、基于注解的IoC初始化
3.1 扫描及注册beandefinition
3.2 自动装配bean
四、refresh()方法源码解读
4.1 prepareRefresh()
4.2 refreshBeanFactory()
4.3 prepareBeanFactory()
4.4 postProcessBeanFactory()
4.5 invokeBeanFactoryPostProcessors()
4.6 registerBeanPostProcessors()
4.7 initMessageSource()
4.8 initApplicationEventMulticaster()
4.9 onRefresh()
4.10 registerListeners()
4.11 finishBeanFactoryInitialization(beanFactory)
4.12 finishRefresh()
IoC(控制反转)就是把原来代码里需要实现的对象创建、依赖,反转给容器来帮忙实现。我们需要创建一个容器,同时需要一种描述来让容器知道要创建的对象和对象的关系。这个描述的最具体的表现就是我们看到的配置文件。
DI(Dependency Injection,依赖注入) 就是指对象被动接收依赖类而不自己主动去找,换句话说,就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象时主动将它依赖的类注入给它。
Spring IoC 从代码层面来说,有3个核心的抽象类:
ApplicationContext接口的实现类通过持有一个BeanFactory接口实例,来完成bean的自动装配工作,它们之间的抽象关系可以用下图来表示:
ApplicationContext接口是Spring容器的核心抽象,有多个实现子类,使用多结构继承,其具体实现子类中有3个常用的类:
ClassPathXmlApplicationContext:从classpath下加载bean的配置文件FileSystemXmlApplicationContext:从系统路径下加载bean的配置文件AnnotationConfigApplicationContext:基于注解的方式读取bean的配置
SpringBoot基于注解编程,管理注解的Bean定义的容器有两个: AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext。这两个是专门处理Spring注解方式配置的容器,直接依赖于将注解作为容器配置信息来源的IoC容器。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的Web版本,两者的用法以及对注解的处理方式几乎没有区别。AnnotationConfigWebApplicationContext的类继承结构如下图所示:
Spring中Bean的创建是典型的工厂模式,这一系列的Bean工厂,为开发者管理对象之间的依赖关系提供了很多便利和基础服务,在Spring中有许多IoC容器的实现供用户选择,其类关系结构图如下:
其中,BeanFactory作为最顶层的一个接口类,定义了IoC容器的基本功能规范,BeanFactory有三个重要的子类:ListableBeanFactory、HierachicalBeanFactory和AutowireCapableBeanFactory。
Spring 将需要自动实例化的对象称为bean对象,使用了BeanDefinition抽象接口来描述bean对象:包括bean的名称,scope,是否懒加载等。在初始扫描包路径下的所有类时,会将类的信息放到Map<String, BeanDefinition> beanDefinitionMap 这个map中,其中key为bean的name。
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 内部的注解。
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);
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(); }
在分析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的基础。
4. @Component及其派生注解标记的类,@Configuration 标记的类,是在bean扫描阶段就被添加到beanDefinition集合中了,而作用于类上的@Import 注解 和作用于方法的@Bean 注解(自定义返回Bean对象),以及@Enablexxx注解,是通过调用BeanFactory后置处理器扫描来实现的。
BeanFactory.getBean 方法
在分析具体流程源码前,应该先了解下 BeanFactory.getBean 方法, Spring使用该方法创建所有的bean对象,AbstractBeanFactory 实现了该方法,该方法的调用流程如下图所示:
主要流程为getBean() -> doGetBean() -> createBean() -> doCreateBean()。
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); } }
refreshBeanFactory():刷新或者创建一个BeanFactory,默认的beanFactory实例对象在父类GenericApplicationContext的构造方法里面创建:
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
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()); } }
postProcessBeanFactory(beanFactory):BeanFactory准备工作完成后进行的后置处理工作,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置,默认实现为空。
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 代理的核心类。
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);
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);
initApplicationEventMulticaster():初始化事件派发器:
1)、获取BeanFactory
2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
onRefresh():留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑。
registerListeners():给容器中将所有项目里面的ApplicationListener接口的实现类注册进来:
1、从容器中拿到所有的ApplicationListener
2、将每个监听器添加到事件派发器中;
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3、派发之前步骤产生的事件;
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();
finishRefresh(),完成BeanFactory的初始化创建工作;IOC容器就创建完成,流程如下:
1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor() 加入到容器;
2)、getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
4)、liveBeansView.registerApplicationContext(this);