Spring IOC容器源码解析
文章目录
一、AnnotationConfigApplicationContext
初始化调用了AnnotationConfigApplicationContext的构造方法。
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(MainConfig.Class);
在传参的构造方法中执行了三步,
1、调用无参够造方法,
2、注册配置类,
3、容器刷新
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// 调用构造方法
this();
// 注册配置类,MainConfig.Class
this.register(annotatedClasses);
// 容器刷新
this.refresh();
}
AnnotationConfigApplicationContext 继承了GenericApplicationContext(通用上下文)
子类在初始化时,默认会调用父类的无参构造方法。在GenericApplitionContext的构造方法中,执行了DefaultListableBeanFactory(BeanFactroy)的初始化。
this.beanFactory = new DefaultListableBeanFactory();
因为DefaultListableBeanFactory 是实现BeanFactory接口的功能最全的实现类。
AnnotationConfigApplicationContext本身的构造方法则执行了AnnotatedBeanDefinitionReader(bean定义读取器) 与 ClassPathBeanDefinitionScanner(bean定义扫描器) 的初始化
二、详细
1.this()构造方法
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// 注解的bean定义读取器
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
// 注解的bean定义读取器初始化
this.reader = new AnnotatedBeanDefinitionReader(this);
// 类路径下的bean定义扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
AnnotationConfigApplicationContext 的自身的构造方法执了两步。
一是创建“注解的bean定义读取器”
这里面主要注册了spring内部注解的bean定义,如常用的@CONFIGURATION、@AUTOWIRED。
二是创建了“类路径下的bean定义扫描器”
这个类主要为bean定义注册器配置了过滤方法(默认过滤方法是@ComponentScan扫描@Component)。
同时继承的父类的构造方法也执行了,新建了一个BeanFactory(DefaultListableBeanFactory)对象。
- AnnotatedBeanDefinitionReader的初始化
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 调用bean定义读解器的构造方法,将创建好的环境放入构造方法。
// getOrCreateEnvironment(registry) 创建或获取环境
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
// Bean定义的注册器
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
/*
【重要】注册注解Bean定义的配置解析器
@Configuration、@AutoWired、@Required等注解的Bean定义在这一步进行配置
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
- ClassPathBeanDefinitionScanner的初始化
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
// getOrCreateEnvironment(registry) 获取或创建环境,
// 在前面的"注解的Bean定义扫描器"初始化时已经创建了,直接从缓存中读取。
// useDefaultFilters:是否使用默认的扫描策略。
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
this(registry, useDefaultFilters, environment, registry instanceof ResourceLoader ? (ResourceLoader)registry : null);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// 如果为true,调用默认的扫描策略
if (useDefaultFilters) {
//@Component、@Controlle、@Service、@Repository注解的bean定义添加
this.registerDefaultFilters();
}
this.setEnvironment(environment);
this.setResourceLoader(resourceLoader);
}
/**
默认的扫描策略
@Component、@Controlle、@Service、@Repository注解的bean定义添加
*/
java protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException var4) {
}
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException var3) {
}
}
2 register注册配置类
register(MainConfig.Class) 这个方法是调用“注解bean定义读取器”将自定义的配置类的bean定义注册到bean定义注册器。
public void registerBean(Class<?> annotatedClass) {
//调用注册bean定义的方法
this.doRegisterBean(annotatedClass, (Supplier)null, (String)null, (Class[])null);
}
//注册bean定义的具体方法
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
.......
// 注册MainConfig中的bean的bean定义
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
3 refresh() 容器刷新
refresh()容器刷新是Spring容器的重点方法,有12个方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//刷新前的预处理;
this.prepareRefresh();
/*
获取BeanFactory;默认实现是DefaultListableBeanFactory,
在AnnotatedBeanDefinitionReader初始化时已经创建,从缓存中读取
*/
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//BeanFactory的预准备工作(BeanFactory进行一些设置,
//比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
this.prepareBeanFactory(beanFactory);
try {
//BeanFactory准备工作完成后进行的后置处理工作
this.postProcessBeanFactory(beanFactory);
// beanFactory后置处理器
this.invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
this.registerBeanPostProcessors(beanFactory);
//初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
this.initMessageSource();
//初始化事件派发器(事件多播器)
this.initApplicationEventMulticaster();
this.onRefresh();
//注册应用的监听器。
//就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
this.registerListeners();
//初始化所有剩下的非懒加载的单例bean
this.finishBeanFactoryInitialization(beanFactory);
//完成context的刷新。
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
总结
以上就是IOC容器的初始化过程,主要就是三步,创建注解的bean定义读取器,加载spring内部的bean定义,创建类路径下的bean定义扫描器,设置扫描器的过滤方法,然后注册自定义的配置类的bean定义,最后调用容器刷新。容器刷新是spring的重点方法,后面需着重分析。