Spring5源码解析(扫描bean)
测试用例代码块
//AppConfig.java类
@ComponentScan({"com.llsydn"})
@Configuration
public class AppConfig {
@Bean
public ConfigDao1 configDao1(){ //自己写一个configDao1类即可
return new ConfigDao1();
}
@Bean
public ConfigDao2 configDao2(){ //自己写一个configDao2类即可
configDao1();
return new ConfigDao2();
}
}
//IndexDao.java类
@Component
public class IndexDao {
public void query(){
System.out.println("query");
}
}
//Test.java类
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
IndexDao indexDao = ac.getBean(IndexDao.class);
System.out.println(indexDao);
indexDao.query();
}
- 这里我是直接用AnnotationConfigApplicationContext类初始化spring的环境,这个类是基于注解配置应用上下文(即是用注解的方式初始化一个spring容器)
Spring中用来注解Bean定义的类有两个:
AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex。
AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的web版本
两者的用法以及对注解的处理方式几乎没有什么差别
通过分析这个类我们知道注册一个bean到spring容器有两种办法:
一、直接将注解Bean注册到容器中:(参考)public void register(Class<?>... annotatedClasses)
但是直接把一个注解的bean注册到容器当中也分为两种方法
1、在初始化容器时注册并且解析
2、也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处理。
二、通过扫描指定的包及其子包下的所有类
扫描其实同上,也是两种方法,初始化的时候扫描,和初始化之后再扫描
下面进入spring容器初始化源码分析
- (1) AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
public class AnnotationConfigApplicationContext extends GenericApplicationContext
/**
* 这个类顾名思义是一个reader,一个读取器
* 读取什么呢?还是顾名思义AnnotatedBeanDefinition意思是读取一个被加了注解的bean
* 这个类在构造方法中实例化的
*/
private final AnnotatedBeanDefinitionReader reader;
/**
* 同意顾名思义,这是一个扫描器,扫描所有加了注解的bean
* 同样是在构造方法中被实例化的
*/
private final ClassPathBeanDefinitionScanner scanner;
/**
* 初始化一个bean的读取和扫描器
* 何谓读取器和扫描器参考上面的属性注释
* 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()
* 去注册配置类(javaconfig),并调用refresh()方法刷新容器,
* 触发容器对注解Bean的载入、解析和注册过程
*/
public AnnotationConfigApplicationContext() {
/**
* 父类的构造方法
* 创建一个读取注解的Bean定义读取器
* 什么是bean定义?BeanDefinition
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
//可以用来扫描包或者类,继而转换成bd
//但是实际上我们扫描包工作不是scanner这个对象来完成的
//是spring自己new的一个ClassPathBeanDefinitionScanner
//这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这里创建一个AnnotationConfigApplicationContext对象,主要是做了3个主要的操作。
1.创建一个new DefaultListableBeanFactory() 是一个Bean工厂容器
2.创建一个new AnnotatedBeanDefinitionReader(this),是Bean的读取器
3.创建一个new ClassPathBeanDefinitionScanner(this),是Bean的扫描器
为什么这里会创建一个DefaultListableBeanFactory()实例的beanFactory?
1.这个beanFactory主要是用来存放Spring管理的Bean对象,一个Bean存放的工厂。
2.怎么会调用了这步new DefaultListableBeanFactory()?因为AnnotationConfigApplicationContext继承了GenericApplicationContext,即在创建AnnotationConfigApplicationContext对象,会先执行父类GenericApplicationContext的构造方法。所以这里是在父类的构造方法中,执行了new DefaultListableBeanFactory()创建了一个beanFactory对象。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
AnnotationConfigApplicationContext 继承了GenericApplicationContext
GenericApplicationContext 实现了 BeanDefinitionRegistry
- 即有:AnnotationConfigApplicationContext 也实现了BeanDefinitionRegistry,AnnotationConfigApplicationContext 也是一个registry类。
- 这个registry比较重要,registry有registerBeanDefinition(注册一个bean定义到bean工厂)、getBeanDefinition(从bean工厂获取一个Bean定义)等功能。所以AnnotationConfigApplicationContext 也是有可以往bean工厂中注册bean的能力。
//创建一个bean读取器过程分析:
this.reader = new AnnotatedBeanDefinitionReader(this);
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.registry = registry; //将registry赋值
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
//主要方法
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
//获取到刚创建完的DefaultListableBeanFactory对象,然后给这个对象的某些属性赋值。
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//给Spring容器添加Spring内部的特殊Bean对象(7个)
//1.往BeanDefinitionMap注册一个ConfigurationClassPostProcessor
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
//而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//2.往BeanDefinitionMap注册一个AutowiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
//MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//3.往BeanDefinitionMap注册一个RequiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//4.往BeanDefinitionMap注册一个CommonAnnotationBeanPostProcessor
// 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));
}
//5.往BeanDefinitionMap注册一个PersistenceAnnotationBeanPostProcessor
// 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));
}
//6.往BeanDefinitionMap注册一个EventListenerMethodProcessor
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));
}
//7.往BeanDefinitionMap注册一个DefaultEventListenerFactory
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;
}
//将**Processor类型的对象,注册到bean工厂中
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//这里主要的代码,将bean定义注册到bean工厂当中
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
这里创建一个AnnotatedBeanDefinitionReader对象,主要是做了2个主要的操作:
1.给在GenericApplicationContext()刚创建的beanFactory对象的某些属性赋值:beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);(主要能解析@Order注解和@Priority)
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());(提供处理延迟加载的功能)2.往bean工厂中注册6个spring内部对象,主要是**BeanPostProcessor类型的对象。(Spring的扩展点之一)
这里特别重要的类是ConfigurationClassPostProcessor,这个类完成bean的扫描。
- (2)ac.register(AppConfig.class);
/**
* 注册单个bean给容器
* 比如有新加的类可以用这个方法
* 但是注册之后需要手动调用refresh方法去触发容器解析注解
*
* 有两个意思:
* 他可以注册一个配置类
* 他还可以单独注册一个bean
*/
public void register(Class<?>... annotatedClasses) {
this.reader.register(annotatedClasses);
}
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
public void registerBean(Class<?> annotatedClass) {
//真正的注册bean的方法
doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
/**
* 根据指定的bean创建一个AnnotatedGenericBeanDefinition
* 这个AnnotatedGenericBeanDefinition可以理解为一个数据结构
* AnnotatedGenericBeanDefinition包含了类的其他信息,比如一些元信息:scope,lazy等等
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
/**
* 判断这个类是否需要跳过解析
* 通过代码可以知道spring判断是否跳过解析,主要判断类有没有加注解
*/
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//不知道
abd.setInstanceSupplier(instanceSupplier);
/**
* 得到类的作用域
*/
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
/**
* 把类的作用域添加到数据结构结构中
*/
abd.setScope(scopeMetadata.getScopeName());
/**
* 生成类的名字通过beanNameGenerator
*/
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/**
* 处理类当中的通用注解
* 分析源码可以知道他主要处理
* Lazy DependsOn Primary Role等等注解
* 处理完成之后processCommonDefinitionAnnotations中依然是把他添加到数据结构当中
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
/**
* 如果在向容器注册注解Bean定义时,使用了额外的限定符注解则解析
* 关于Qualifier和Primary前面的课当中讲过,主要涉及到spring的自动装配
* 这里需要注意的
* byName和qualifiers这个变量是Annotation类型的数组,里面存不仅仅是Qualifier注解
* 理论上里面里面存的是一切注解,所以可以看到下面的代码spring去循环了这个数组
* 然后依次判断了注解当中是否包含了Primary,是否包含了Lazyd
*/
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
如果配置了@Primary注解,如果加了则作为首选
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
//懒加载,前面加过
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
//如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个根据名字自动装配的限定符
//这里难以理解,后面会详细介绍
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
/**
* 这个BeanDefinitionHolder也是一个数据结构(beanName,beanDefinition,aliases[])
*/
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
/**
* ScopedProxyMode 这个知识点比较复杂,需要结合web去理解
*/
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/**
* 把上述的这个数据结构注册给registry
* registy就是AnnotatonConfigApplicationContext
* AnnotatonConfigApplicationContext在初始化的時候通过调用父类的构造方法
* 实例化了一个DefaultListableBeanFactory
* *registerBeanDefinition里面就是把definitionHolder这个数据结构包含的信息注册到
* DefaultListableBeanFactory这个工厂
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
//将beanDefinition注册到bean工厂中
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException{
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
//DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
//主要代码:
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
ac.register(AppConfig.class);的主要作用是将AppConfig类注册到bean工厂中。
即是到目前为止,bean工厂中已经有了7个beanDefinition。
- (3)ac.refresh(); 这里最重要的一步,实现bean的扫描和初始化阶段
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备工作包括设置启动时间,是否激活标识位,
// 初始化属性源(property source)配置
prepareRefresh();
//返回一个factory 为什么需要返回一个工厂
//因为要对工厂进行初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//准备工厂
prepareBeanFactory(beanFactory);
try {
//这个方法在当前版本的spring是没用任何代码的
//可能spring期待在后面的版本中去扩展吧
postProcessBeanFactory(beanFactory);
//在spring的环境中去执行已经被注册的 factoryBean processors
//设置执行自定义的ProcessBeanFactory 和spring内部自己定义的 (重要,实现bean的扫描等)
invokeBeanFactoryPostProcessors(beanFactory);
//注册beanPostProcessor
registerBeanPostProcessors(beanFactory);
initMessageSource();
//初始化应用事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
//实例化单列的bean对象(重要)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
throw ex;
}
}
}
- prepareRefresh
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
//这个方法目前没有子类去实现
//估计spring是期待后面的版本有子类去实现吧
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
- obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
//GenericApplicationContext
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
- prepareBeanFactory
/**
* 配置其标准的特征,比如上下文的加载器ClassLoader和post-processors回调
* 此处的beanFactory参数等于DefaultListableFactory
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//bean表达式解释器,能够获取bean当中的属性在前台页面
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//对象与string类型的转换 <property red="dao">
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加一个后置管理器
//ApplicationContextAwareProcessor 能够在bean中获得到各种*Aware(*Aware都有其作用)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//意思就是:使得ApplicationContextAware接口实现类在自动装配时不能被注入applicationContext对象的依赖。
//(不能使用xml的set方法或构造方式注入,但是可以用@Autowired注入)
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 interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//意思是如果自定义的Bean中没有名为"systemProperties"和"systemEnvironment"的Bean,
// 则注册两个Bena,Key为"systemProperties"和"systemEnvironment",Value为Map,
// 这两个Bean就是一些系统配置和系统环境信息
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
//直接往beanFactory工厂中添加bean对象(该对象已经被new出来的)
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());
}
}
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException();
}
addSingleton(beanName, singletonObject);
}
}
//往singletonObjects对象中添加bean实例
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
prepareBeanFactory方法的主要作用:
1.给beanFactory的某些属性赋值。
2.给beanFactory添加BeanPostProcessor:ApplicationContextAwareProcessor(可以插手bean的初始化,扩展点之一)
3.给beanFactory添加系统配置和系统环境信息等实例。
- invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//这个地方需要注意getBeanFactoryPostProcessors()是获取手动给spring的BeanFactoryPostProcessor
//自定义并不仅仅是程序员自己写的
//自己写的可以加companent也可以不加
//如果加了getBeanFactoryPostProcessors()这个地方得不得,是spring自己扫描的
//为什么得不到getBeanFactoryPostProcessors()这个方法是直接获取一个list,
//这个list是在AnnotationConfigApplicationContext被定义
//所谓的自定义的就是你手动调用AnnotationConfigApplicationContext.addBeanFactoryPostProcesor();
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//定义了两个list存放
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//自定义的beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}else {
regularPostProcessors.add(postProcessor);
}
}
//这个currentRegistryProcessors 放的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//BeanDefinitionRegistryPostProcessor 等于 BeanFactoryPostProcessor
//getBeanNamesForType 根据bean的类型获取bean的名字ConfigurationClassPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//这个地方可以得到一个BeanFactoryPostProcessor,因为是spring默认在最开始自己注册的
//为什么要在最开始注册这个呢?
//因为spring的工厂需要许解析去扫描等等功能
//而这些功能都是需要在spring工厂初始化完成之前执行
//要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后
//因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
//所以这里spring'在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
//在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
//ConfigurationClassPostProcessor那么这个类能干嘛呢?可以参考源码
//下面我们对这个牛逼哄哄的类(他能插手spring工厂的实例化过程还不牛逼吗?)重点解释
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序不重要,况且currentRegistryProcessors这里也只有一个数据
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并list,不重要(为什么要合并,因为还有自己的)
registryProcessors.addAll(currentRegistryProcessors);
//最重要。注意这里是方法调用
//执行所有BeanDefinitionRegistryPostProcessor(开始执行扫描包)
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//执行完成了所有BeanDefinitionRegistryPostProcessor
//这个list只是一个临时变量,故而要清除
currentRegistryProcessors.clear();
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();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//执行BeanFactoryPostProcessor的回调,前面不是吗?
//前面执行的BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor的回调
//这是执行的是BeanFactoryPostProcessor postProcessBeanFactory
//ConfuguratuonClassPpostProcssor
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//自定义BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 这里为什么要再重复执行一遍?
// 因为经过上面的ConfuguratuonClassPpostProcssor对bean的扫描,扫描到的bean对象有可能是实现了BeanFactoryPostProcessor接口的,所以要这这些扫描处理的bena进行再一步处理
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
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
}
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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//因为只有一条数据:ConfigurationClassPostProcessor
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
//ConfigurationClassPostProcessor
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException();
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException();
}
this.registriesPostProcessed.add(registryId);
//执行
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//定义一个list存放app 提供的bd(项目当中提供了@Compent)
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取容器中注册的所有bd名字
//7个
String[] candidateNames = registry.getBeanDefinitionNames();
/**
* Full , Lite
*/
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
//果BeanDefinition中的configurationClass属性为full或者lite,则意味着已经处理过了,直接跳过
//这里需要结合下面的代码才能理解
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//判断是否是Configuration类,如果加了Configuration下面的这几个注解就不再判断了
// 还有 add(Component.class.getName());
// candidateIndicators.add(ComponentScan.class.getName());
// candidateIndicators.add(Import.class.getName());
// candidateIndicators.add(ImportResource.class.getName());
//beanDef == appconfig
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//BeanDefinitionHolder 也可以看成一个数据结构
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 排序,根据order,不重要
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
//如果BeanDefinitionRegistry是SingletonBeanRegistry子类的话,
// 由于我们当前传入的是DefaultListableBeanFactory,是SingletonBeanRegistry 的子类
// 因此会将registry强转为SingletonBeanRegistry
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
//是否有自定义的
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
//SingletonBeanRegistry中有id为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator
//如果有则利用他的,否则则是spring默认的
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
//实例化ConfigurationClassParser 为了解析各个配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//实例化2个set,candidates用于将之前加入的configCandidates进行去重
//因为可能有多个配置类重复了
//alreadyParsed用于判断是否处理过
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//很重要(扫描bean)
parser.parse(candidates);
parser.validate();
//map.keyset
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
/**
* 这里值得注意的是扫描出来的bean当中可能包含了特殊类
* 比如ImportBeanDefinitionRegistrar那么也在这个方法里面处理
* 但是并不是包含在configClasses当中
* configClasses当中主要包含的是importSelector
* 因为ImportBeanDefinitionRegistrar在扫描出来的时候已经被添加到一个list当中去了
*/
//bd 到 map 除却普通 (将import的bean注册到bean工厂)(重要)
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
//由于我们这里进行了扫描,把扫描出来的BeanDefinition注册给了factory
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
}
//ConfigurationClassParser
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
//根据BeanDefinition 的类型 做不同的处理,一般都会调用ConfigurationClassParser#parse 进行解析
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//解析注解对象,并且把解析出来的bd放到map,但是这里的bd指的是普通的
//何谓不普通的呢?比如@Bean 和各种beanFactoryPostProcessor得到的bean不在这里put
//但是是这里解析,只是不put而已
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
}
//处理延迟加载的importSelect?为什么要延迟加载,估计就是为了延迟吧
processDeferredImportSelectors();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 处理Imported 的情况
// 就是当前这个注解类有没有被别的类import
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an imports.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass);
do {
//具体的实现(重要)
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
//一个map,用来存放扫描出来的bean(注意这里的bean不是对象,仅仅bean的信息,因为还没到实例化这一步)
this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 处理内部类
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);
}
}
// 处理@ComponentScan注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
//扫描普通类=componentScan=com.llsydn
//这里扫描出来所有@Component
//并且把扫描的出来的普通bean放到map当中
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
//检查扫描出来的类当中是否还有configuration
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//检查到有的,再执行一次parse方法
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
/**
* 上面的代码就是扫描普通类----@Component
* 并且放到了map当中
*/
// Process any @Import annotations
//处理@Import imports 3种情况
//ImportSelector
//普通类
//ImportBeanDefinitionRegistrar
//这里和内部地柜调用时候的情况不同
/**
* 这里处理的import是需要判断我们的类当中时候有@Import注解
* 如果有这把@Import当中的值拿出来,是一个类
* 比如@Import(xxxxx.class),那么这里便把xxxxx传进去进行解析
* 在解析的过程中如果发觉是一个importSelector那么就回调selector的方法
* 返回一个字符串(类名),通过这个字符串得到一个类
* 继而在递归调用本方法来处理这个类
*
* 判断一组类是不是imports(3种import)
*/
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
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));
}
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
//ComponentScanAnnotationParser,扫描普通的@component
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//扫描包(重点)
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
//ClassPathBeanDefinitionScanner
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//扫描basePackage路径下的java文件
//符合条件的并把它转成BeanDefinition类型
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//解析scope属性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//如果这个类是AbstractBeanDefinition的子类
//则为他设置默认值,比如lazy,init destory
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//检查并且处理常用的注解
//这里的处理主要是指把常用注解的值设置到AnnotatedBeanDefinition当中
//当前前提是这个类必须是AnnotatedBeanDefinition类型的,说白了就是加了注解的类
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//将bean定义注册到bean工厂中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
//扫描包,将class转成beanDefinition
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
//利用asm技术读取class文件,并将class文件转成beanDefinition
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//asm 读取class文件
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
candidates.add(sbd);
}
}
}
}
}
}
return candidates;
}
invokeBeanFactoryPostProcessors的主要作用:
1.执行spring内部的**BeanFactoryPostProcessor的方法。(ConfigurationClassPostProcessor)ConfigurationClassPostProcessor主要的作用就是实现bean的扫描,并实现将beanDefinition注册到bean工厂中
BeanFactoryPostProcessor
spring的扩展点之一:
1.实现该接口,可以在spring的bean创建之前修改bean的定义属性。
2.spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,
3.并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。
4.可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。
5.BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。
BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor 。是对BeanFactoryPostProcessor 的扩展,新增了postProcessBeanDefinitionRegistry方法,可以往Bean工厂中,注册一个BeanDefinition对象。
//上面的是扫描普通的bean
//处理@Import的3种情况(正常类;ImportSelector类;ImportBeanDefinitionRegistrar类)
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
//反射实现一个对象
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
//回调
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
//递归,这里第二次调用processImports
//如果是一个普通类,会斤else
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//添加到一个list当中和importselector不同
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
// 否则,加入到importStack后调用processConfigurationClass 进行处理
//processConfigurationClass里面主要就是把类放到configurationClasses
//configurationClasses是一个集合,会在后面拿出来解析成bd继而注册
//可以看到普通类在扫描出来的时候就被注册了
//如果是importSelector,会先放到configurationClasses后面进行出来注册
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process imports candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
processImports,处理import的类,主要是处理3种。
- 普通的bean
- 实现了 importSelector的bean(可以注册多个类的String数组字符串)
- 实现了ImportBeanDefinitionRegistrar
- import普通的bean,会先加入到importStack后调用processConfigurationClass 进行处理,放入到configurationClasses后面进行出来注册。
- import的是importSelector,会先实例化这个ImportSelector 类,然后执行该selector的selectImports方法,获取要注入到spring的bean工厂的类数组字符串,然后 对该String[]数组,进行再一次调用processImports方法处理,最终都是会进入到import普通bean的步骤,即:会先加入到importStack后调用processConfigurationClass 进行处理,放入到configurationClasses后面进行出来注册。
- import的是ImportBeanDefinitionRegistrar,会先实例化这个ImportBeanDefinitionRegistrar类,然后将它添加到一个list当中和importselector不同。
对于import的bean处理,是在 ConfigurationClassPostProcessor # processConfigBeanDefinitions()方法处理,即下面代码:
/**
* 这里值得注意的是扫描出来的bean当中可能包含了特殊类
* 比如ImportBeanDefinitionRegistrar那么也在这个方法里面处理
* 但是并不是包含在configClasses当中
* configClasses当中主要包含的是importSelector
* 因为ImportBeanDefinitionRegistrar在扫描出来的时候已经被添加到一个list当中去了
*/
//bd 到 map 除却普通
this.reader.loadBeanDefinitions(configClasses);
//ConfigurationClassBeanDefinitionReader
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
//如果一个类是被import的,会被spring标准
//早这里完成注册
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
//@Bean
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//xml
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//注册Registrar
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
//将import和importSelector注入的bean,注册到bean工厂中
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isDebugEnabled()) {
logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
}
}
//将ImportBeanDefinitionRegistrar注入的bean,注册到bean工厂中
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
总结:spring扫描类分了4种情况
- 普通类,扫描到即刻注册到beanDefinitionMap中。
- import(普通类),扫描到先存放到configurationClasses一个map集合。
- import(importSelector),扫描到遍历循环一个一个的放到configurationClasses一个map集合。
- import(importBeanDefinitionRegistrar),扫描到之后存放到importBeanDefinitionRegistrars一个map集合中。
备注:对于import的类,spring是在扫描之后,调用了loadBeanDefinitions方法将扫描到import的类注册到beanDefinitionMap中。
full和lite的主要作用:
- 当一个bean加了@Configuration注解,即是full全注解类。
- 当一个bean加了@Component、@ComponentScan、@Import、@ImportResource等注解,即是lite
备注:full全注解类,spring会为该类生成一个cglib代理类。
对于加了@Configuration注解的类,spring会对该类使用cglib产生一个代理类。
为什么需要使用cglib代理?AppConfig类,使用@Bean注入了两个bean,在configDao2()方法中调用了configDao1()方法,这里就是为了防止configDao1对象被创建两次的问题。
备注:cglib是基于继承的。
是在invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);方法执行的。
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
//因为只有一条数据ConfigurationClassPostProcessor
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
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);
}
//给配置类产生cglib代理
//为什么需要产生cglib代理?(给AppConfig产生代理类,configDao2()方法调用了configDao1()方法)
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
//判断是否是一个全注解类
//扫描是全注解类?full和lite的关系
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException("");
}
else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
logger.warn("");
}
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty()) {
return;
}
//完成cglib代理
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
if (configClass != null) {
//完成对全注解类的cglib代理
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(""));
}
beanDef.setBeanClass(enhancedClass);
}
}
}
}
}
# ConfigurationClassEnhancer
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
//判断是否被代理过
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
if (logger.isDebugEnabled()) {
logger.debug("");
}
return configClass;
}
//没有被代理cglib代理
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
if (logger.isDebugEnabled()) {
logger.debug(String.format("");
}
return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
//增强父类,地球人都知道cglib是基于继承来的
enhancer.setSuperclass(configSuperClass);
//增强接口,为什么要增强接口?
//便于判断,表示一个类以及被增强了(实现BeanFactoryAware,为了获得BeanFactory对象)
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
//不继承Factory接口
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// BeanFactoryAwareGeneratorStrategy是一个生成策略
// 主要为生成的CGLIB类中添加成员变量$$beanFactory
// 同时基于接口EnhancedConfiguration的父接口BeanFactoryAware中的setBeanFactory方法,
// 设置此变量的值为当前Context中的beanFactory,这样一来我们这个cglib代理的对象就有了beanFactory
// 有了factory就能获得对象,而不用去通过方法获得对象了,因为通过方法获得对象不能控制器过程
// 该BeanFactory的作用是在this调用时拦截该调用,并直接在beanFactory中获得目标bean
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
//过滤方法,不能每次都去new
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
//CALLBACK_FILTER:setCallbackFilter
private static final Callback[] CALLBACKS = new Callback[] {
//增强方法,主要控制bean的作用域
//(不用每一次都去调用new)
new BeanMethodInterceptor(),
//设置一个beanFactory
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
};
private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
/**
* 用于拦截@Bean方法的调用,并直接从BeanFactory中获取目标bean,而不是通过执行方法。
*/
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
// enhancedConfigInstance 代理
// 通过enhancedConfigInstance中cglib生成的成员变量$$beanFactory获得beanFactory。
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// Determine whether this bean is a scoped-proxy
Scope scope = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
if (factoryBean instanceof ScopedProxyFactoryBean) {
// Scoped proxy factory beans are a special case and should not be further proxied
}
else {
// It is a candidate FactoryBean - go ahead with enhancement
return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
}
//一个非常牛逼的判断
//判断到底是new 还是get
//判断执行的方法和调用方法是不是同一个方法
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
//如果是同一个方法:调用代理对象的方法,执行被代理类的方法(即configDao1()的new ConfigDao1()实例化configDao1对象)
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
//不是同一个方法:调用getBean方法。(即在执行configDao2()方法,调用了configDao1()方法)
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
//判断他是否正在创建
boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
try {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, false);
}
boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
if (useArgs && beanFactory.isSingleton(beanName)) {
for (Object arg : beanMethodArgs) {
if (arg == null) {
useArgs = false;
break;
}
}
}
//beanFactory.getBean
//这个方法spring就写的非常牛逼,在bean实例化的会重点解析
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName));
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
if (beanInstance.equals(null)) {
if (logger.isDebugEnabled()) {
logger.debug(""));
}
beanInstance = null;
}
else {
String msg = "";
try {
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore - simply no detailed message then.
}
throw new IllegalStateException(msg);
}
}
Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
if (currentlyInvoked != null) {
String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
beanFactory.registerDependentBean(beanName, outerBeanName);
}
return beanInstance;
}
finally {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, true);
}
}
//判断执行的方法和调用方法是不是同一个方法
private boolean isCurrentlyInvokedFactoryMethod(Method method) {
Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
return (currentlyInvoked != null && method.getName().equals(currentlyInvoked.getName()) &&
Arrays.equals(method.getParameterTypes(), currentlyInvoked.getParameterTypes()));
}
}
}
这里给加了@Configuration注解的类使用cglib动态代理产生的代理类:
- 主要是使用BeanMethodInterceptor类,在bean被实例化的时候,进行拦截。
- 怎么做到在configDao2()方法中调用了configDao1(),而configDao1没有被创建两次?
主要是判断执行的方法和调用方法是不是同一个方法,即在执行configDao2()方法的时候,调用了configDao1()方法。
所以在再次执行configDao1()方法时候,判断出发起调用的主方法是configDao2,即执行方法和调用方法不是同一方法。3.1 如果是同一个方法:调用代理对象的方法,执行被代理类的方法
cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
3.2 不是同一个方法:调用getBean方法
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
spring初始化总结
spring的扩展点(5个)
- BeanPostProcessor
插手bean的实例过程、实例化之后,在bean没有被spring的bean容器管理之前干活。
经典场景:@PostConstruct、aop
- BeanFactoryPostProcessor
spring的bean容器当中任意的一个bean被new出来之前执行,针对beanFactory来建设。
经典场景:ConfigurationClassPostProcessor#postProcessBeanFactory,针对配置类(@Configuration注解)加上cglib代理。
- BeanFactoryRegistryPostProcessor
是BeanFactoryPostProcessor的子类,在BeanFactoryPostProcessor之前执行?因为源码当中先遍历BeanFactoryRegistryPostProcessor(有spring提供的,还有自定义)自定义的先执行。
经典场景:ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry,扫描、3种import的扫描、@Bean的扫描,判断配置类是否是一个完整的配置类
- ImportSelector
通过这个方法selectImports返回一个类名(全名)数组,把他变成beanDefinition,动态添加beanDefinition(这个BeanDefinition是写死的,因为这个BeanDefinition是有spring内部生成的,我们无法改变这些BeanDefinition)
- ImportBeanDefinitionRegistrar
registerBeanDefinitions方法可以得到BeanDefinitionRegistry故而可以动态添加BeanDefinition,还可以改变BeanDefinition。
经典场景:mybatis的mapperScan