Spring注解启动:AnnotationConfigApplicationContext原理
入口代码:
public class SpringAnnotationStarter {
public static void main(String[] args) {
//创建一个新的AnnotationConfigApplicationContext,从给定的组件类派生bean定义并自动刷新上下文。
new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);
}
}
在上面的测试中,使用的AnnotationConfigApplicationContext来刷新上下文,传入参数是我们定义的配置类。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
点进去可以发现,首先是调用空参构造器,然后是注册配置类,最后刷新,所以从这三个步骤进行梳理
1. this()
这就是一个空参构造器。
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
从代码可以看出,是给reader和scanner两个属性进行赋值。
reader的类型是AnnotatedBeanDefinitionReader ,点进去看源码,这是个适配器,也就是adapter,用于bean类的编程注册,解析带有注解的bean的beanDefinition。在reader的赋值如下:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
传入当前类,并且根据当前环境调用重载的构造进行上下文创建,getOrCreateEnvironment看名字大概就是没有创建,有就获取,这就不看了,直接去关注重载的构造器
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);
}
这里ConditionEvaluator点进去是为context赋值,根据上下文创建一个ConditionContextImpl。
关键在于AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
AnnotationConfigUtils
是一个Spring
内部工具类,用于识别注解配置类中的bean
定义,registerAnnotationConfigProcessors是为在给定的注册表中注册所有后置处理器,也就是PostProcessor。包括一些核心注解,形如:if(!registry.containsBeanDefinition(XXXXXXXXXXXXX))
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//从上下文拿到beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//解析注解ConfigurationClassPostProcessor ,方便后续注册BeanDefinition
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//解析@Autowired ,方便后续注册BeanDefinition
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
最后将BeanDefinition集合返回。到这里reader就初始化完成了
然后scanner类型是为给定的bean工厂创建一个新的ClassPathBeanDefinitionScanner
一直往里点可以得到:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();//注册@Component的默认Filters
}
setEnvironment(environment);//设置要在解析占位符和评估@Conditional注释组件类时使用的环境。
setResourceLoader(resourceLoader);//将ResourceLoader设置为用于资源位置。这通常是一个ResourcePatternResolver实现。
}
从这里可以得出,主要用于扫描注解的设置。
2. register(componentClasses);
在上一步中,通过reader和scanner分别对BeanFactory以及核心的注解,过滤器,环境等进行了配置。
register方法中,传入的是我们写的配置类。
跟进,发现调用的是reader的register方法。
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
继续跟进:
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
遍历所有传入的componentClasses,对Bean进行注册,再跟进,我们会进入真正的注册逻辑doRegisterBean
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//声明BeanDefinition,下面都是填充属性
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置用于创建bean实例的回调(可能为null)
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//作用域
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理abd中的通用注解,@Lazy、@Primary、@DependsOn、@Role以及@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//下面这段关于qualifiers判断是否有限定注解@Primary@Lazy
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));
}
}
}
//处理回调
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//将abd封装成BeanDefinitionHolder,然后对BeanDefinition注册
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//向BeanFactory进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
到这里相当于把我们写的配置注册到Spring了。
3. refresh();
这个方法,点进去就是一个refresh方法,对应Spring的初始化中的refresh,org.springframework.context.support.AbstractApplicationContext#refresh,对应着Spring生命周期 下面这段是之前学Spring的时候在网上找的,大致流程如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备此上下文以进行刷新、设置其启动日期和活动标志以及执行任何属性源的初始化。
prepareRefresh();//刷新前的预处理
// 创建初始化BeanFactory,这个过程中loadBeanDefinitions()方法,输入beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
// 1.设置BeanFactory的类加载器为ApplicationContex的类加载器
// 2.设置beanFacory的语言表达式处理器
try {
this.postProcessBeanFactory(beanFactory);
// 执行BeanFactoryPostProcessor的方法,BeanFactory的后置处理器
// 在BeanFactory标准初始化之后执行的,调用各种BeanFactoryPostProcessor
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程
this.registerBeanPostProcessors(beanFactory);
// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析).
this.initMessageSource();
// 初始化上下文的事件机制
this.initApplicationEventMulticaster();
// 可以用于子类实现在容器刷新时自定义逻辑初始化
this.onRefresh();
// 注册时间监听器,将ApplicationListener注册到容器中来
this.registerListeners();
// 初始化所有剩下的单实例bean,单例bean在初始化容器时创建。
this.finishBeanFactoryInitialization(beanFactory);
// 发布完成事件,结束初始化过程
this.finishRefresh();
}
catch (BeansException ex) {
...
}
}
}