这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
之前我们知道了spring ioc的加载过程, 具体如下图. 下面我们就来对照下图, 看看ioc加载的源代码.
下面在用装修类比, 看看个个组件都是怎么工作的.
接下来是源码分析的整体结构图. 对照上面的思路梳理出来的
一、源码分析的入口
通常,我们的入口都是从main方法进入. 这里我们也来定义一个main方法
public class MainStarter {
public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class );
context.scan("package name");
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}
}
顺便再来看看还有哪些相关的类
/**
* 这是一个配置类,
* 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
* 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
*/
@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {
}
这个类有一个注解@Configuration, 这样这个类会被扫描成bean
还有一个注解@ComponentScan(backPackage = {"com.lxl.www.iocbeanlifecicle"}) 他表示, 请扫描com.lxl.www.iocbeanlifecicle包下所有的类.
com.lxl.www.iocbeanlifecicle 这个包下还有哪些类呢? 我们来看看项目结构
这是这个包下完整的项目结构.
下面会逐渐说明, 每个类的用途
二. 最重要的类BeanFactory
我们知道在将一个class加载为bean的过程中BeanFactory是最最重要的, 那么他是何时被加载的呢?
我们来跟踪一下带有一个参数的构造方法AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// retister配置注册类
register(componentClasses);
// ioc容器shua新接口--非常重要
refresh();
}
这就是AnnotationConfigApplicationContext初始化的时候做的三件事
第一件事: this(); //调用自身的无参构造方法. 同时调用父类的构造方法
第二件事: register(componentClasses); // 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图
第三件事: refresh(); // 这是ioc容器刷新, 非常重要. 无论是spring boot还是spring mvc都有这个方法. 这个方法包含了整个spring ioc加载的全生命流程. 也是我们要重点学习的方法
下面来看看BeanFactory是何时被加载进来的呢?
在初始化方法的时候调用了自身的无参构造函数, 在调用自身无参构造函数的时候, 同时会调用父类的无参构造函数.
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
......
}
父类是GenericApplicationContext, 其无参构造函数就做了一件事
public GenericApplicationContext() {
// 构造了一个BeanFactory.
// 在调用GenericApplicationContext父类构造函数, 为ApplicationContext spring上下文对象初始化beanFactory
// 为什么初始化的是DefaultListableBeanFactory呢?
// 我们在看BeanFactory接口的时候发现DefaultListableBeanFactory是最底层的实现, 功能是最全的.
// 查看
this.beanFactory = new DefaultListableBeanFactory();
}
初始化DefaultListableBeanFactory.
问题: BeanFactory有很多, 为什么初始化的时候选择DefaultListableBeanFactory呢?
我们来看看DefaultListableBeanFactory的结构. 快捷键option + command + u --> Java Class Diagrams
通过观察, 我们发现, DefaultListableBeanFactory实现了各种各样的BeanFactory接口, 同时还是先了BeanDefinitionRegistry接口.
也就是说, DefaultListableBeanFactory不仅仅有BeanFactory的能力, 同时还有BeanDefinitionRegistry的能力. 它的功能是最全的.
所以, 我们使用的是一个功能非常强大的类Bean工厂类.
AnnotationConfigApplicationContext继承了GenericApplicationContext,
而 GenericApplicationContext 实现了AnnotationConfigRegistry接口.
所以AnnotationConfigApplicationContext有AnnotationConfigRegistry的能力.
三. bean定义读取器AnnotatedBeanDefinitionReader
接着上面, 第一步调用的是this(). 也就是AnnotationConfigApplicationContext的无参构造函数. 在这个无参构造函数里一共做了两件事情
public AnnotationConfigApplicationContext() {
/**
* 创建了一个Bean定义的读取器.
* 完成了spring内部BeanDefinition的注册(主要是后置处理器)
* 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
*/
this.reader = new AnnotatedBeanDefinitionReader(this); /**
* 创建BeanDefinition扫描器
* 可以用来扫描包或者类, 进而转换为bd
*
* Spring默认的扫描包不是这个scanner对象
* 而是自己new的一个ClassPathBeanDefinitionScanner
* Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
*
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
* 通过调用context.scan("package name");扫描处理配置类
* 扫描
*/
this.scanner = new ClassPathBeanDefinitionScanner(this );
}
-
初始化AnnotatedBeanDefinitionReader.
-
初始化ClassPathBeanDefinitionScanner
我们先来看看AnnotatedBeanDefinitionReader
在这里的描述中, 我们知道BeanDefinitionReader是要去扫描配置或者注解, 如果理解为销售的话, 就是扫描楼盘. 这里面就有我们的潜在用户. 也就是我们需要将其转换为bean的对象.
那么初始化的时候,AnnotatedBeanDefinitionReader做了什么呢?
重点看这句
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册注解类型配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors( this .registry);
}
注册注解类型配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors( this .registry);
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 获取到beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
/**
* 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
* 没有则添加
*/
if (beanFactory != null) {
if (! (beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (! (beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// BeanDefinitionHolder: 为BeanDefinition设置名字和别名
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
if (! registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 2. 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor Autowired注解bean的后置处理器, 则添加一个
if (! registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
// 3. 检查对JSR-250的支持, 如果rigistry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个
if (jsr250Present && ! registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个
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));
}
// 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个
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));
}
// 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个
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;
}
在这里注册了6个后置处理器.