本文基于Spring5注解版进行分析
主要分析Spring扫包工作流程@ComponentScan(),Bean创建流程,Bean生命周期
Spring Bean创建过程传送门
Maven依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
</dependencies>
启动Spring代码
public class StartSpring {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext
= new AnnotationConfigApplicationContext(StartConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println("BeanName:" + name);
}
}
}
点开AnnotationConfigApplicationContext查看源码
/**
* 创建新的注释配置应用程序上下文,派生bean定义,并自动刷新上下文。
* @param 一个或多个组件类 例如,标注有@Configuration的类
* {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
this()的初始化工作我已经在上篇文章讲解过了Spring 底层源码解析(开篇)
重点:
在了解Spring底层源码的时候,应该要先知道IOC容器的核心类有哪些,核心成员属性有哪些。Bean定义 和 创建好的单实例Bean存放在哪里。
请记住以下标记重点的属性,下面分析要用到。
DefaultListableBeanFactory:IOC容器,存放Bean的定义…
/**
* 默认的Bean工厂
*/
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** 可以直接通过类型依赖注入的Bean. */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** bean定义对象的映射,由bean名称来标识。 {@link BeanDefinition} Bean定义信息*/
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** 单例和非单例bean名称的映射,由依赖类型键入。 */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** 按依赖类型键入的单例bean名称的映射. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** 注册到容器的 Bean name 重点*/
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** 手动注册的单实例Bean name 例如 environment, systemProperties, systemEnvironment */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
}
DefaultSingletonBeanRegistry:DefaultListableBeanFactory继承了此类,存放所有的单实例Bean…
/**
* 共享bean实例的通用注册器
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** 存放所有的单实例Bean 由Bean name 标识 重点 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 存放所有单实例 ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 早期单例对象的缓存: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 已注册的单实例Bean name, containing the bean names in registration order. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** 要执行销毁方法的单实例 Bean: bean name to disposable instance. */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
/** 包含bean名称之间的映射: bean名称到bean包含的一组bean名称. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** 依赖bean名称之间的映射:bean名称到依赖bean名称集. */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** 从属bean名称之间的映射:bean名称为bean的依赖项设置一组bean名称. */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
}
本文讲解 register(componentClasses),和 refresh()方法。
register(componentClasses):注册传入的Config配置类。
向IOC容器中注册StartConfig.class Bean的定义。doRegisterBean
public class AnnotatedBeanDefinitionReader {
/**
* 从给定的bean类注册一个bean,从类声明的注解
* @param beanClass bean类型
* @param instanceSupplier 创建bean实例的回调
* @param name bean的显式名称
* @param qualifiers 要考虑的特定限定符注释(如果有),除了bean类级别的限定符之外
* @param definitionCustomizers 一个或多个用于定制工厂的{@link BeanDefinition}的回调,例如设置惰性初始化或主标志
* @param <T>
*/
<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
/* 创建 注解Bean的定义对象 */
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
/* 检查 {@link Conditional}@Conditional注解 是否能够注册该Bean */
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
/* 设置一个回调创建Bean */
abd.setInstanceSupplier(instanceSupplier);
/* 解析 {@link Scope} @Scope注解信息 */
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
/* 设置Bean的作用域 {prototype, singleton} */
abd.setScope(scopeMetadata.getScopeName());
/* 拿到BeanName */
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/* @Lazy @Primary @DependsOn @Role @Description注解解析 且为Bean定义对象的对应属性赋值 */
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));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
/* 创建 BeanDefinition持有对象(包装对象) */
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
/* 对 {@link Scope} @Scope.proxyMode 属性解析,指定组件是否应配置为作用域代理 如果是,代理应该基于接口还是基于子类。*/
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/* 向容器中(BeanFactory)注册Bean定义 */
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
从源码分析得知:register(componentClasses); 只是注册了传入进来的配置类,并没有注册其他包下的类,比如@Service @Controller @Repository之类的。那么扫包注册其他类就应该在refresh();里面完成的
开始分析 refresh(),(刷新容器,启动容器)
/**
- 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新此上下文。 预处理工作
prepareRefresh();
// 告诉子类刷新内部bean工厂。拿到Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备好bean工厂,以便在这种情况下使用。
// 配置工厂的标准上下文特征,例如上下文的类加载器和后处理器。
// 注册Spring默认的Bean
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
// 在上下文中调用注册为beans的工厂后置处理器。
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean后置处理器。
registerBeanPostProcessors(beanFactory);
// 为此上下文初始化消息源。
initMessageSource();
// 为此上下文初始化事件多主控。
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊beans。
onRefresh();
// 检查侦听器beans并注册它们。
registerListeners();
// 实例化所有剩余的(非惰性初始化)单件。
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布对应事件。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单件,以避免悬空资源。
destroyBeans();
// 重置“活动”标志。
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 重置Spring核心中的公共内省缓存,因为我们
// 可能不再需要单例beans的元数据了..
resetCommonCaches();
}
}
}
}
refresh()方法里面执行的方法很多,每个方法也是各司其职。带着以下疑问点,开始对每个方法进行分析:
- @ComponentScan()在那一步开始扫包工作的?
- Bean是怎么创建的?
- @Autowired是怎么注入的?
- Bean的创建过程是怎样的(Bean的生命周期)?
1.0.0: prepareRefresh(); 准备工作,设置容器状态
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 为刷新准备此上下文,设置其启动日期和活动标志以及执行属性源的任何初始化
*/
protected void prepareRefresh() {
// 切换到激活状态。
this.startupDate = System.currentTimeMillis(); // 当前时间
this.closed.set(false); // 是否关闭
this.active.set(true); // 是否活跃
// ... 省略输出日志代码
// 初始化上下文环境中的任何占位符属性源, 例如: ${}(是一个空方法 由子类实现)
initPropertySources();
// 验证标记为必需的所有属性都是可解析的:
// 参考 ConfigurablePropertyResolver#setRequiredProperties
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<>();
}
}
2.0.0: obtainFreshBeanFactory(); 获取BeanFactory
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 告诉子类刷新内部bean工厂。
* @return BeanFactory实例
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 调用子类的实现方法 参考 GenericApplicationContext.refreshBeanFactory 设置SerializationId
// 代码:GenericApplicationContext.refreshBeanFactory() { this.beanFactory.setSerializationId(getId()); }
refreshBeanFactory();
// 拿到BeanFactory实例
// 代码:GenericApplicationContext.getBeanFactory() {return this.beanFactory; }
return getBeanFactory();
}
}
3.0.0: prepareBeanFactory(beanFactory); 准备好bean工厂
配置工厂的标准上下文特征,例如上下文的类加载器和后处理器。注册Spring默认的Bean。
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 配置工厂的标准上下文特征,
* 例如上下文的类加载器和后处理器。
* @param beanFactory 要配置的BeanFactory
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader()); // 设置类加载器 {@link Launcher.AppClassLoader} 应用类加载器
// 为bean定义值中的表达式指定解析策略。EL表达式解析
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加一个应用于所有bean创建过程的属性编辑器注册器。
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 用上下文回调配置bean工厂。
/**
* 以下Aware接口的后置处理器
* ApplicationContextAware,MessageSourceAware,ApplicationEventPublisherAware,
* ResourceLoaderAware,EmbeddedValueResolverAware,EnvironmentAware
*/
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接口未在普通工厂中注册为可解析类型。
// MessageSource作为bean注册(并为自动连接找到)。
/**
* registerResolvableDependency 注册可以直接根据类型依赖注入的对象
* 列如:
* @Autowired
* private BeanFactory beanFactory;
* @Autowired
* private BeanFactory ResourceLoader;
* @Autowired
* private BeanFactory ApplicationEventPublisher;
* @Autowired
* private BeanFactory ApplicationContext;
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 将用于检测内部beans的早期后处理器注册为应用程序侦听器。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检测一个加载时间编织器,并准备编织,如果发现。
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 为类型匹配设置临时类加载器。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册默认环境beans。
/**
* 可以用 ApplicationContext.getBean("name") 获取到注册的单实例Bean
*
* ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getBean("environment");
* Map systemProperties = (Map) applicationContext.getBean("systemProperties");
* Map systemEnvironment = (Map) applicationContext.getBean("systemEnvironment");
*/
// String ENVIRONMENT_BEAN_NAME = "environment";
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
// 当前Spring环境 包含systemProperties,systemEnvironment
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
// Map对象,系统属性 可以自己输出看看
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
// Map对象,系统环境的属性值 可以自己输出看看
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
}
3.0.0 处总结:
- beanFactory.registerResolvableDependency() 可以手动的注册可以依赖注入的Bean。
- beanFactory.addBeanPostProcessor() 可以手动的注册后置处理器。
- beanFactory.registerSingleton() 可以手动的注册一个单实例Bean,但不支持依赖注入。
4.0.0: postProcessBeanFactory(beanFactory);
告诉子类BeanFactory准备好了,是一个空方法,由子类实现。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
}
5.0.0: ==invokeBeanFactoryPostProcessors(beanFactory);==重点的一个方法 着重分析
执行BeanFactoryPostProcessors Bean工厂后置处理器
再执行该方法前断点查看 beanFactory.beanDefinitionMap(Bean注册的定义信息对象Map集合),里面只有一个startConfig是我们定义的Bean。执行完后就有了userService, userDao, userController定义的Bean了。而且BeanDefinition是ScannedGenericBeanDefinition类型。
以上可以得知,@CompentScan扫包是容器在执行BeanFactoryPostProcessor(Bean工厂后置处理器)的时候工作的。
invokeBeanFactoryPostProcessors(beanFactory);的源码
调用了PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()静态方法
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 实例化并调用所有注册的BeanFactoryPostProcessor beans,
* 如果给出明确的顺序,请遵守。
* <p> 必须在单例实例化之前调用。
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 重点分析)
// 执行 BeanFactoryPostProcessors 是{@link PostProcessorRegistrationDelegate}的一个静态方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 检测一个加载时间编织器,并准备编织,如果在此期间发现
// 例如,通过配置类后处理器注册的@Bean方法)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
/**
* 返回将要应用的BeanFactoryPostProcessors列表
* 到内部BeanFactory。
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
}
5.0.1: PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 执行Bean工厂后置处理器
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 如果有的话,首先调用BeanDefinitionRegistryPostProcessors
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// ... 省略代码 for循环执行beanFactoryPostProcessors.postProcessBeanFactory()
//不要初始化factory这里的意思是:我们需要保留所有常规的beans
//未初始化让bean工厂后处理器应用到它们!
//在实现
// PriorityOrdered、Ordered等。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
* 重点分析 BeanDefinitionRegistryPostProcessors 后置处理器工作
*/
// 首先,调用实现优先级排序的 BeanDefinitionRegistryPostProcessors。
// 拿到 BeanDefinitionRegistryPostProcessor 类型的Bean定义,
// 默认有一个 {@link ConfigurationClassPostProcessor} 在实例化的时候添加的
// BeanName = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
/**
* 从容器中根据 BeanName Bean类型获取Bean 如果没有则创建
* 流程后面分析
*/
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 根据优先级排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 开始执行后置处理器
*
* (重点分析)
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
/**
* ... 省略很多代码....
*
* 省略代码就是处理 BeanFactoryPostProcessor 后置处理器
*/
}
/**
* 调用给定的BeanDefinitionRegistryPostProcessor后处理器beans。
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
// 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry)
// 后置处理回调方法
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
// 排序 优先执行
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
comparatorToUse = OrderComparator.INSTANCE;
}
postProcessors.sort(comparatorToUse);
}
}
从以上代码看出,会优先执行BeanDefinitionRegistryPostProcessor这个后置处理器。它继承了BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor后置处理器用于注册Bean的。
断点调试会拿到一个实现了BeanDefinitionRegistryPostProcessor接口的Bean。
Bean = ConfigurationAnnotationProcessor
ConfigurationAnnotationProcessor Bean定义会在初始化容器的时候添加。
参考:this.reader = new AnnotatedBeanDefinitionReader(this);
5.0.2:invokeBeanDefinitionRegistryPostProcessors() 95行
执行后置通知方法
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
/**
* 从注册表中的配置类派生更多的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);
}
}
5.0.3:processConfigBeanDefinitions(registry); 核心方法
处理配置Bean的定义 基于的注册表构建并验证配置模型,由于代码量很多,截取重要部分
重点分析 parser.parse(candidates);
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
/**
* Bean定义已经作为配置类进行了处理
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
/**
* 此处省略很多代码 ....
*/
// 解析每个@Configuration类 配置类解析器 {@Configuration, @Import}
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**
* 开始解析
* 重点关心这里
*/
parser.parse(candidates); // {@link ConfigurationClassParser} ConfigurationClassParser.parse()
// 检查注册的Bean
parser.validate();
/**
* 此处省略很多代码 ....
*/
}
while (!candidates.isEmpty());
}
}
5.0.4:parser.parse(candidates); 开始解析配置类
class ConfigurationClassParser {
// 解析
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
// 会执行这行代码
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
/**
* 此处省略很多代码 ....
*/
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
// 开始解析
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
/**
* 重点分析
* @param configClass
* @throws IOException
*/
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// @Conditional 检查
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationCondition.ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
/**
* 此处省略很多代码 ....
*/
/**
* 这里开始扫包 重点
*/
// 递归处理配置类及其超类层次结构。
SourceClass sourceClass = asSourceClass(configClass);
do {
// 重点分析 解析配置类
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
}
5.0.5:doProcessConfigurationClass()
解析配置类
class ConfigurationClassParser {
protected final SourceClass doProcessConfigurationClass(SourceClass sourceClass) throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 首先递归处理任何成员(嵌套)类
processMemberClasses(configClass, sourceClass);
}
// 处理任何 @PropertySource 注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理 @ComponentScan 组件扫描注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 配置类用 @ComponentScan 组件扫描->立即执行扫描来注释
/**
* this.componentScanParser.parse 这个是我们重点关心的
* 会进行扫包,将 @Component, @Service, @Controller, @Repository注解的类注册到容器
*
* componentScanParser.parse --> {@link ComponentScanAnnotationParser} ComponentScanAnnotationParser.parse
*/
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查任何进一步配置类的扫描定义集,并在需要时递归解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理 @Import 注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 处理单个 @Bean 方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理接口上的默认方法
processInterfaces(configClass, sourceClass);
// 处理父类(如果有)
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 找到父类,返回其注释元数据并递归 递归再来执行一次
return sourceClass.getSuperClass();
}
}
//没有父类类->处理完成
return null;
}
}
5.0.6:componentScanParser.parse()
@ComponentScan注解解析处理
/**
* 解析 {@link ComponentScan} 注解.
*/
class ComponentScanAnnotationParser {
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// 一个检测类路径中候选bean的bean定义扫描器,
//向给定的注册表注册相应的bean定义({@code BeanFactory}
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
/**
* 省略一大推代码...
* 作于 @ComponentScan参数解析
*
* basePackages = ComponentScan.basePackages 属性
*/
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
5.0.7:scanner.doScan()
开始扫包
/**
* 一个检测类路径中候选bean的bean定义扫描器,
* 向给定的注册表注册相应的bean定义({@code BeanFactory}
*/
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
/**
* 查找{basePackages}此包下所有符合条件注册到容器的类,
*/
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 拿到 Bean name
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// @Lazy, @Primary, @DependsOn, @Role, @Description 检查这些注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查Bean是否注册了
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
/**
* 向容器注册Bean
*/
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
/**
* 返回所有扫包注册的 Bean
*/
return beanDefinitions;
}
}
以上就是 @Configuration 配置类解析,解析内容讲解在5.0.6,扫包注册Bean在5.0.7
5.1.0:
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 执行Bean工厂后置处理器,在前面已经注册了所有的Bean之后,会拿到Sping自带的BeanFactoryPostProcessor,也会拿到我们自定义的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor去执行后置方法
流程图:
总结:invokeBeanFactoryPostProcessors(beanFactory);
执行Bean工厂后置处理器,其中有一个子接口:BeanDefinitionRegistryPostProcessor Bean定义的注册后置处理器,Spring容器在初始化的时候,注册了一个ConfigurationClassPostProcessor(BeanDefinitionRegistryPostProcessor 实现类),ConfigurationClassPostProcessor此后置处理器用于解析@Configuration配置类,处理@PropertySource, @Import, @ImportResource, @Bean 这些注解。
重点:Bean扫包注册及@Bean,@Import是在BeanFactoryPostProcessor(Bean工厂后置处理器)的子接口BeanDefinitionRegistryPostProcessor(Bean定义的后置处理器)的实例类(ConfigurationClassPostProcessor)中完成工作的。
6.0.0:registerBeanPostProcessors(beanFactory);
注册并实例化所有bean后置处理器
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 注册并实例化所有bean后置处理器。会有优先级排序
* <p>必须在应用程序beans的任何实例化之前调用。
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
}
6.0.1:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
对已经注册到容器中的且实现了 BeanPostProcessors接口的,先进行实例化。会有优先级排序。
/**
* 抽象应用程序上下文的后处理器处理委托。
*/
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 在以下情况下,注册记录信息消息的BeanPostProcessorChecker
// bean是在bean后处理器实例化期间创建的,即
// bean没有资格被所有bean后处理器处理。
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 在实现优先级的后处理器之间进行分离排序, {@link 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);
}
}
// 优先注册 实现了 {@link PriorityOrdered}接口的BeanPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 再注册实现了 {@link Ordered}接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
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);
// 注册所有常规的 BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,重新注册所有内部 BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 将用于检测内部beans的后处理器重新注册为应用程序侦听器
// 将其移动到处理器链的末端(用于拾取代理等)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
7.0.0: initMessageSource();
针对于国际化问题的MessageSource
8.0.0:initApplicationEventMulticaster();
初始化事件派发器
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 初始化事件派发器 ApplicationEventMulticaster.
* 如果上下文中没有定义,则使用 {@link SimpleApplicationEventMulticaster}。
* @see org.springframework.context.event.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() + "]");
}
}
}
}
9.0.0: onRefresh();
容器初始化Bean之前的工作,是一个空方法,交由子类实现
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 可被覆盖以添加特定于上下文的刷新工作的模板方法
* 可被覆盖以添加特定于上下文的刷新工作的模板方法
* <p>此实现为空
* @throws BeansException in case of errors
* @see #refresh()
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
// 对于子类:默认什么都不做。
}
}
10.0.0: registerListeners();
注册监听器
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 添加将应用程序侦听器实现为侦听器的beans。
* 不影响其他监听器,可以不做Bean添加。
*/
protected void registerListeners() {
// 首先注册静态指定的侦听器。
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 从容器中获取所有实现了 {@link ApplicationListener} 接口的bean name
// 放入 applicationListenerBeans 集合中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
/**
* 这里先发布早期的监听器
*
* 这里大概给子类用的
*/
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
}
11.0.0:finishBeanFactoryInitialization(beanFactory);
初始化剩下的单实例Bean,@Service, @Controller,@Repository,@Component,@Bean等等之类的注解Bean,由于此方法功能复杂,留给下一篇单独讲。
12.0.0:finishRefresh();
容器初始化完成,发布相应的事件 (ContextRefreshedEvent)容器启动事件
/**
* 抽象的应用程序上下文
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* 完成此上下文的刷新,调用生命周期处理器的onRefresh()方法并发布
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// 清除上下文级资源缓存(例如来自扫描的ASM元数据)。
clearResourceCaches();
// 为此上下文初始化生命周期处理器。 参考:{@link DefaultLifecycleProcessor}
initLifecycleProcessor();
// 首先将刷新传播到生命周期处理器。
getLifecycleProcessor().onRefresh();
// 发布容器启动事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
}
Spring Bean创建过程传送门
觉得对您有帮助,就点个赞呗。😀