Spring启动流程
- 话外音
- 环境准备
- 整体流程简图
- AnnotationConfigApplicationContext
- 1、this()
- 2、register(componentClasses)
- 3、refresh
- prepareRefresh
- obtainFreshBeanFactory
- prepareBeanFactory(beanFactory)
- postProcessBeanFactory
- invokeBeanFactoryPostProcessors(beanFactory);
- registerBeanPostProcessors(beanFactory);
- initMessageSource();
- initApplicationEventMulticaster();
- onRefresh();
- registerListeners();
- finishBeanFactoryInitialization(beanFactory);
- finishRefresh();
话外音
- 真是受益良多啊,开始是想做个系统的整理与复习,然后思考了一下某个地方是如何实现,以及自己该怎么讲述这些东西;
- 于是开始代码 debug,不知道不觉就陷入了大山,越走越深,不清楚的越来越多,又一个接一个了解清楚,然后,开始循环了……
- 几个小时后,猛然抬头,啊这…… 好像和我 debug 的初衷有点儿对不上啊……
- 每每念及于此,只能再次对 Spring 这座大山……膜拜啊……
环境准备
废话少说,开始吧!下载Spring5.x源码,导入Idea并构建,创建包扫描类。
@Configuration
@ComponentScan("com.slc")
public class AppConfig {
}
class StartApplication {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//Person类在另外一个文件里面,简单用@Component标注即可,此处不展示
Person bean = context.getBean(Person.class);
}
}
启动项目,成功打印 Person
类的相关信息
整体流程简图
AnnotationConfigApplicationContext
Spring启动过程中,在通过 new AnnotationConfigApplicationContext
这一步骤已经完成了所有bean的扫描和管理。作为整个程序的入口,我们先来简单分析一下 AnnotationConfigApplicationContext
首先分析一下继承图:
提一下几个重要的接口和类:
- BeanFactory:访问Spring Bean的根接口,此接口和实现类实现依赖注入,在获取
Bean 实例
的时候如果当前容器找不到,会从父容器里面找 - BeanDefinitionRegistry:用于保存 Bean 定义
(BeanDefinition)
的接口,定义了保存、查看、移除相关的接口 - DefaultListableBeanFactory: Spring容器管理的核心类,具备成熟的容器管理能力,并且继承了
DefaultSingletonBeanRegistry
定义的 Spring 三级缓存 (详情点击) - AnnotationConfigRegistry:注册配置注册表,定义注册和扫描配置类的方法
- ApplicationContext:定义基本功能方法(通过继承各种接口),包括访问 Bean 工厂,国际化,事件监听,加载文件资源等方法定义
- AbstractApplicationContext: 抽象上下文,主要完成
registerBeanPostProcessors 即BeanPostProcessors的注册功能
- GenericApplicationContext:继承
AbstractApplicationContext
,以模板方法定义部分功能,需要各种子类的实现,并且 持有DefaultListableBeanFactory引用
总的来说 AnnotationConfigApplicationContext
实现了以下功能:
- 完成了组件类输入,包含
@Configuration
、@Component
和JSR-330兼容的类eg:@Resource
, - 并且可以注册和进行类路径扫描,是一个独立的应用程序上下文,
- 类似的类还有
ClassPathXmlApplicationContext
,属于不同的功能实现。
点击 AnnotationConfigApplicationContext
的构造方法,开始解读:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//1.初始化读取器和扫描器,
//2.指定bean factory实现类(DefaultListableBeanFactory),
//3.获取相关的环境餐撒胡配置,如系统变量参数和进程启动参数
//4.添加默认的6个内部处理器的BeanDefinition到factory的map中,其中jpa的处理器需要判断环境中是否导入相关包
this();
//注册一个或多个AppConfig,即包扫描类到BeanDefinitionMap中,包括@Condition,@Primary等属性值的读取,
register(componentClasses);
//初始化各种类
refresh();
}
父类初始化 DefaultListableBeanFactory
在调用构造器内的方法前,由于java的类加载机制,需要先进行父类的静态代码块和构造器的初始化
AnnotationConfigApplicationContext
的父类 GenericApplicationContext
进行了 DefaultListableBeanFactory
的初始化操作。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
1、this()
点进 this
方法,初始化了一个读取器和扫描器。核心内容在里面,先跟进Reader的初始化操作。
public AnnotationConfigApplicationContext() {
//读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
//扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
AnnotatedBeanDefinitionReader初始化
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册注解配置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
跳过方法重写部分,有两个入参:BeanDefinitionRegistry
和Environment
AnnotationConfigApplicationContext
本就实现了BeanDefinitionRegistry
接口,调用时通过this
将自身作为入参传了进来。此时向上转型为BeanDefinitionRegistry
(明确职责),可以理解为现在需要使用BeanDefinitionRegistry
定义的方法,而该接口负责BeanDefinition
注册的相关内容。Environment
通过getOrCreateEnvironment
获得,如果没有手动设置过的话,最终得到一个StandardEnvironment
对象,其实就是用来获取 java 启动时的参数和系统变量。
重点在于AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
这一行代码。
AnnotationConfigUtils.registerAnnotationConfigProcessors
主动调用 AnnotationConfigUtils,先加载静态代码块,这里先判断环境中是否存在jpa和@Resource,为之后添加Spring的内置处理器作出准备。
static {
ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader();
jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader);
jpaPresent = ClassUtils.isPresent("javax.persistence.EntityManagerFactory", classLoader) &&
ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
}
点进registerAnnotationConfigProcessors,是个重写方法,跳过
//方法重写,跳过
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
进入具体的方法内部,逐行分析
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//为BeanFactory提供@Ordered和Priority支持
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//为BeanFactory提供对@Lazy和限定符解析的支持
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//根据判断,为BeanDefinitionMap中添加默认的spring处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
/**
* 注册到BeanDefinitionMap中,并放回BeanDefinitionHolder
* @param registry 工厂
* @param definition definition
* @param beanName bean的名称
* @return 持有BeanDefinition的类
*/
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
- 首先是为工厂设置一些默认的支持:
@Ordered
和@Priority
支持,为Bean Factory
提供对@Lazy
和限定符解析的支持 - 判断当前
BeanDefinitionMap
中是否存在某些内容,没有的话就添加对应的内容。
正如方法名registerAnnotationConfigProcessors
(注册注解配置处理器)所描述的一样,这个方法的主要功能是在BeanDefinitionMap
中添加Spring内部提供的各种处理器,其中包含以下6个处理器:
ConfigurationClassPostProcessor
:用于对@Configuration
的解析支持,是所有处理器中第一个添加的,很重要AutowiredAnnotationBeanPostProcessor
:用于支持自动装配;CommonAnnotationBeanPostProcessor
:用于支持JSR-250约束,包括@Resource
、@PostConstruct
、@PreDestroy
的注解解析;PersistenceAnnotationBeanPostProcessor
:用户支持JPA持久层解析,会判断当前是否有持久层对应的jar包,不一定会加载;EventListenerMethodProcessor
:对@EventListener
注解的支持,DefaultEventListenerFactory
:同样是对Spring Event
的支持,和EventListenerMethodProcessor
共同作用
总结
AnnotatedBeanDefinitionReader
的初始化,大概完成了以下几件事情:
- 为
Bean Factory
设置属性,主要是对@Ordered
、@Priority
、@Lazy
的解析支持; - 注册5~6个spring内部使用的解析处理器,用于后面各种解析的支持;
ps:这里需要明确一个概念,目前仅仅只是在BeanDefinitionMap
中添加了内部处理器,并没有加载
ClassPathBeanDefinitionScanner初始化
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
this(registry, useDefaultFilters, environment, (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
//为@Component注册默认过滤器,隐式注册@Repository、@Service和@Controller等注释
//并且支持JAVAEE6 提供的@ManagedBean和JSR-330的@Named
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
跳过一层层的方法调用,查看重点:registerDefaultFilters
registerDefaultFilters
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
//在过滤器中添加@Component扫描支持
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 在过滤器中添加@ManagedBean扫描支持
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// 如果不支持JSR-250,Java EE 6,直接跳过
}
try {
// 在过滤器中添加@Named扫描支持
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// 如果不支持JSR-330 直接跳过
}
}
总结
ClassPathBeanDefinitionScanner
主要功能如下:
- 为
BeanFactory
添加扫描过滤器:添加@Component
和可能存在的JSR-250
+JSR330
注解; - 提供该类的
scan
方法,为后面包扫描提供支持;
疑问:如何扫描@Service、@Controller等注解
这里有一个注意点:只添加了@Component的拦截支持,如何扫描到@Service
、@Controller
等等注解的呢?
参看registerDefaultFilters
的Spring源码注释:
/**
* Register the default filter for {@link Component @Component}.
* <p>This will implicitly register all annotations that have the
* {@link Component @Component} meta-annotation including the
* {@link Repository @Repository}, {@link Service @Service}, and
* {@link Controller @Controller} stereotype annotations.
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available.
*
*/
protected void registerDefaultFilters() {
//...
}
翻译一下:
- 为@Component注册默认过滤器。
- 这将隐式注册所有具有@Component元注释的注释,包括@Repository 、 @Service和@Controller型注释。
- 还支持 Java EE 6 的javax.annotation.ManagedBean和 JSR-330 的javax.inject.Named注释(如果可用)。
并没有提到如何隐式注册@Repository 、 @Service的。
简单提一下如何实现的:
查看这几个高级注解,可以发现他们的注解定义上均有@Component修饰
首先要明确一个概念:
- 注解是不能继承的。如果A注解修饰B注解,然后B注解注释某个类,是不能通过类直接获取到A注解的。
- 我们常说的注解的继承指的是,子类获取父类的注解。这并不是注解的继承,出发点在于类。
但是可以间接达到目的,Spring通过获取注解的元注解,然后递归扫描,判断类是否是Spring Bean
(判断方式Spring在5.x进行了优化,暂时不多做研究,但大概的思路就是这样的)
this方法总结
- 初始化读取器和扫描器;
- 间接添加了5到6个
BeanPostProcessor
,为之后的操作提供支持; - 添加各个注解的过滤器,为之后的包扫描提供支持;
2、register(componentClasses)
进入三大方法的第二个:register
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
主要是循环处理componentClasses
(包扫描类可以传入多个),切入重点:doRegisterBean
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//为注册类创建一个AnnotatedGenericBeanDefinition,主要是获取注解信息的方法支持
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//结合 @Condition 来判断是否跳过,本次调用作用不大
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//@Scope属性判断
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 调用beanNameGenerator生成名称,用于BeanDefinitionMap的key
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 为注册类需要注册的BeanDefinition添加各种属性值: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));
}
}
}
// Spring新提供的方法,自定义注册一个 bean,本次调用没用到
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 分装BeanDefinitionHolder,BeanDefinitionHolder持有BeanDefition
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 读取@Scop的proxyMethod属性值,确定代理方式
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册Bean(添加到BeanDefinitionMap中)
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
那么register(componentClasses)
的作用就很明显了:用来注册 AppConfig
的Bean定义。
基本的注释在代码都有提及。
需要注意的是:doRegisterBean
是一个注册Bean的通用方法,里面包含其他componentClasses
的判断。
3、refresh
终于到这个部分了,spring启动流程的精华就在这个方法内部,我们切入主题。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前的准备工作,主要是一些容器状态还有环境的设置
prepareRefresh();
//获取DefaultListableBeanFactory (register中初始化的factory)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//做一些准备工作,初始化容器的一些标准特性
prepareBeanFactory(beanFactory);
try {
//此处AbstractApplicationContext没有实现该方法,留给子类实现,
postProcessBeanFactory(beanFactory);
/**
* 执行实现 BeanFactoryPostProcessors接口的类(并且@Component标注),因为原理是通过getBean(name,class)获取后执行
*
* 1.委托给PostProcessorRegistrationDelegate来进行“调用”这一动作,内部处理存在特殊处理(如:优先级判断决定执行的先后顺序),
* 2.最原始的先后顺序上,先执行为 BeanDefinitionRegistryPostProcessor 的子类,再执行 BeanFactoryPostProcessor 的子类
* --- BeanFactoryPostProcessor
* --- BeanDefinitionRegistryPostProcessor 为前者的子类
*
* 查看spring最开始就加载的配置类之一:ConfigurationClassPostProcessor,该类为spring
* ConfigurationClassPostProcessor
*
*/
invokeBeanFactoryPostProcessors(beanFactory);
//同样委托给PostProcessorRegistrationDelegate 注册需要执行的BeanPostProcessors
registerBeanPostProcessors(beanFactory);
//国际化的一些初始化操作
initMessageSource();
//初始化 ApplicationEventMulticaster到 单例池中,用于管理 ApplicationListener ,默认为 SimpleApplicationEventMulticaster。
initApplicationEventMulticaster();
//模板方法,用于其他Context子类 实例化一些特殊的Bean
onRefresh();
//往 applicationEventMulticaster 添加实现ApplicationListener接口的类
registerListeners();
//初始化所有非 Lazy 的单例 Bean
finishBeanFactoryInitialization(beanFactory);
//完成上下文刷新,会调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent 。
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//Spring original comment----------------- Destroy already created singletons to avoid dangling resources.
destroyBeans();
//Spring original comment----------------- Reset 'active' flag.
cancelRefresh(ex);
//Spring original comment----------------- Propagate exception to caller.
throw ex;
} finally {
//Spring original comment----------------- Reset common introspection caches in Spring's core, since we
//Spring original comment----------------- might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
一行一行来吧:
prepareRefresh
刷新前的准备工作,包括spring状态的设置,一些验证和事件的初始化设置
protected void prepareRefresh() {
//设置为开启状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
//初始化占位符属性源,留给子类实现,在AnnotationConfigApplicationContext没有实现,其他需要的子类应当实现
initPropertySources();
//验证setRequiredProperties指定的每个属性是否存在并解析为非null值。
getEnvironment().validateRequiredProperties();
//存储早期事件监听
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//用来存储早期的事件,在广播器可用后发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}
obtainFreshBeanFactory
获取BeanFactory
,另外CAS设置状态,避免一个Bean Factory
多次刷新。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//refresh校验
refreshBeanFactory();
return getBeanFactory();
}
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
prepareBeanFactory(beanFactory)
做一些准备工作,初始化一些标准特性,比较重要的部分如下:
- 提供了
BeanFactoryProcessor
的支持,在Spring大法属于很重要的环节; - 注册了
ApplicationListener
相关的处理器; registerResolvableDependency
为解决 ”无法找到同接口多实现类“ 提供了一种解决方法,可以在日常中考虑使用(@Qualifier
也不错)- 提供
LoadTimeWeaver
支持
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//上下文类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//设置Bean表达式解析器,在属性填充(populateBean)的时候会用到里面的方法
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//提供属性编辑器,可以自定义,通过实现PropertyEditorSupport接口
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加 BeanFactoryProcessor 支持的重要环节
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略给定的自动装配依赖接口,在addBeanPostProcessor 已经初始化了
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);
//注册早期的 ApplicationListene 处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//果存在的话,提供 LoadTimeWeaver 支持
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//为类型匹配设置一个临时的 ClassLoader。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注册默认的环境类相关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());
}
}
postProcessBeanFactory
该方法在父类 AbstractApplicationContext
中定义,在AnnotationConfigApplicationContext
中并没有实现它。
子类可以通过重写这个方法,在BeanFactory
准备好后进行额外操作。
GenericWebApplicationContext
作为另外的子类,就实现了该方法:添加了ServletContextAwareProcessor
处理器。(有兴趣的可以看看)
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
invokeBeanFactoryPostProcessors(beanFactory);
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//委托
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//如果检测到 LoadTimeWeaver ,则准备编织
//例如通过 ConfigurationClassPostProcessor 注册的 @Bean 方法
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这个方法的主要作用是:实例化并调用所有已注册的 BeanFactoryPostProcessor
,分析一下关键代码。
首先是委托给了PostProcessorRegistrationDelegate
进行调用操作。点进去查看委托的操作。 这部分有点儿意思。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//如果有的话,首先调用 BeanDefinitionRegistryPostProcessors。
Set<String> processedBeans = new HashSet<>();
//如果factory属于BeanDefinitionRegistry,则执行以下逻辑(通过扫描获取哪些BeanFactoryPostProcessor需要执行)
//而else里面则直接执行 beanFactoryPostProcessors 集合里面的内容
//(该类容一般传参的方式为工厂的成员变量 factory.getBeanFactoryPostProcessors())
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//对于DefaultListableBeanFactory而言,此处为Empty -->factory.getBeanFactoryPostProcessors 为空
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
//不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean 未初始化以让 bean 工厂后处理器应用于它们!
// 将实现 PriorityOrdered、Ordered 和其余部分的 BeanDefinitionRegistryPostProcessor 分开。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 1.首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获取BeanDefinitionRegistryPostProcessor 接口定义的类,
//spring内部定义的扫描类,优先级高于 BeanFactoryPostProcessor,为 BeanFactoryPostProcessor的子类
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 2。然后,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 3.最后,调用所有其他 BeanDefinitionRegistryPostProcessor 直到不再出现。
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//现在,调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
//调用在上下文实例中注册的工厂处理器
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean 未初始化以让 bean 工厂后处理器应用于它们!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//将实现 PriorityOrdered、Ordered 和其余部分的 BeanFactoryPostProcessors 分开。
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
/**
* skip - already processed in first phase above
* 已经先调用完毕了,比如ConfigurationClassPostProcessor,该类实现了 BeanDefinitionRegistryPostProcessor 接口
* 而BeanDefinitionRegistryPostProcessor是 BeanFactoryPostProcessor的子类,所以这个集合里面还是会得到该类的名称,
* 所以此处跳过(不做处理)
*/
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 1.首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessors。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 2。然后,调用实现 Ordered 的 BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 3.最后,调用所有其他 BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//清除缓存的 merged bean definitions,因为后处理器可能已经修改了原始元数据,例如替换值中的占位符...
beanFactory.clearMetadataCache();
}
这一段的代码较长,但是重复的段落较多,整体思想还是比较简单的。一层一层的来解析他。
- 首先明确调用此方法的
BeanFactory
,是否是用来注册的(beanFactory instanceof BeanDefinitionRegistry
),否则直接调用该工厂内定义的beanFactoryPostProcessors
本次调用的是DefaultListableBeanFactory
,自然间接继承或实现了BeanDefinitionRegistry
。
我们进入内部复杂的初始化操作。在简单看完这里面的代码之后,我们可以发现一些很有趣的东西:
- 该方法主要是按顺序调用了实现
BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
接口的方法。 - 这个顺序是按照所实现方法上的注解进行判断的,最优先的为
@PriorityOrdered
标注的实现类,其次是@Ordered
,最后是什么都没有的。
重点:beanFactoryPostProcessors加载的优先级判断
其实BeanDefinitionRegistryPostProcessor
是继承BeanFactoryPostProcessor
的子接口
- 那么为什么要spring要区分对待呢?
- 都是
beanFactoryPostProcessors
处理器,按照@PriorityOrdered
→@Ordered
→什么都没有
的顺序处理一次不就可以了吗?
通过断点,我们发现被扫描出来的,实现了BeanDefinitionRegistryPostProcessor
接口的类为:ConfigurationClassPostProcessor
我们之前就提到过了ConfigurationClassPostProcessor
:在registerAnnotationConfigProcessors
中被注册,是第一个被调用的处理器。
ConfigurationClassPostProcessor
负责支持@Configuration
的解析,从作用上来说,应当早于所有其他的beanFactoryPostProcessors
到这里我们需要知道两点就可以了:
- 实现
BeanDefinitionRegistryPostProcessor
的方法 早于 实现beanFactoryPostProcessors
的方法。 - 在
invokeBeanFactoryPostProcessors
中是先处理的前者。二者调用时都是@PriorityOrdered
→@Ordered
→什么都没有
的优先级判断
另外在调用的同时两个接口的实现类会通过getBean()
加载到DefaultListableBeanFactory
持有的由父级的单例池singletonObjects
里面
ConfigurationClassPostProcessor的加载
我们来查看第一个调用并添加到单例池BeanFactory
处理器:ConfigurationClassPostProcessor
究竟做了什么:
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
//对Configuration类进行增强
enhanceConfigurationClasses(beanFactory);
//添加一个 ImportAwareBeanPostProcessor 后置处理器,
//其作用是为EnhanceConfiguration类的beanFactory属性赋值。
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
主要做了两点:
- 为
Configuration
类创建代理; - 添加一个
ImportAwareBeanPostProcessor
后置处理器,为EnhanceConfiguration类的beanFactory属性赋值
这里面牵扯到@ImportAware
的实现原理,篇幅有限,暂不展开。具体内容会在其他博客中详细描述。
总结
invokeBeanFactoryPostProcessors(beanFactory)
完成了以下功能:
- 委托给
PostProcessorRegistrationDelegate
调用beanFactoryPostProcessors
的实现类(包括BeanDefinitionRegistryPostProcessor
); - 加载
beanFactoryPostProcessors
的实现类到单例池里面; - 调用
ConfigurationClassPostProcessor
的postProcessBeanFactory
的方法,创建对应代理,并添加一个ImportAwareBeanPostProcessor
registerBeanPostProcessors(beanFactory);
调用并注册BeanPostProcessors
,原理和invokeBeanFactoryPostProcessors
如出一辙,简单分析一下:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
和BeanFactoryProcessors
类似,同样是委托,此处委托给PostProcessorRegistrationDelegate
进行相关操作。我们直接点进去:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
//注册 BeanPostProcessorChecker,它会在 BeanPostProcessor 实例化期间创建 bean 时记录信息消息,即当 bean 没有资格被所有 BeanPostProcessor 处理时。
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//重新注册处理器以将内部 bean 检测为 ApplicationListeners,将其移动到处理器链的末尾(用于获取代理等)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
大体内容是一样的:按照@PriorityOrdered
→@Ordered
→什么都没有
的优先级调用并注册BeanPostProcessor
不同的地方有以下两个地方:
- 添加了一个
BeanPostProcessorChecker
:这是用于记录某些没有被所有BeanPostProcessor
的Bean
信息。 - 重新注册了
ApplicationListenerDetector
:Spring Event
的相关机制,此时吧``ApplicationListenerDetector`添加到了处理器的末尾
*ps:addBeanPostProcessor
*内部操作时,会先remove,然后再新增,并且放在最后面:addLast方法
initMessageSource();
国际化的一些初始化操作
initApplicationEventMulticaster();
初始化 ApplicationEventMulticaster
。如果上下文中没有定义,则使用 SimpleApplicationEventMulticaster
。
代码如下,没什么好说的。
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() + "]");
}
}
}
onRefresh();
和postProcessBeanFactory
,使个模板方法。交给子类实现。AnnotationConfigApplicationContext
并没有实现它。
例如GenericWebApplicationContext
在这个时候设置了ThemeSource
ThemeSource
:主题资源,web时可能需要,没用过。参考即可。
registerListeners();
往 applicationEventMulticaster 添加实现ApplicationListener接口的类
finishBeanFactoryInitialization(beanFactory);
初始化所有非 Lazy 的单例 Bean
这是 Spring启动流程的重点,这是Spring启动流程的重点,这是Spring启动流程的重点。重要的事说三遍!
循环依赖的解决及三级缓存的设计都在里面。
关于本方法会在另一篇博客里面详细描述。此处不展开
finishRefresh();
完成上下文刷新,会调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent