说明: AbstractApplicationContext是Spring上下文非常关键的一个类,Spring的上下文基本上都是基于继承该类实现扩展的,所以掌握该抽象类是非常重要的。文章写的很杂乱,想到什么就写上了什么,写的不好还请多多包涵。能力和文笔实力有限,仅作抛砖引玉之用。
一、类图介绍
图一:
1. AbstractApplicationContext 抽象应用上下文,是所有Spring应用上下文的基类。
2. DisposableBean 可销毁的bean, bean生命周期结束前调用destory方法。亦可以使用destory-method。
3. DefaultResourceLoader 默认的资源加载器。ClassPathResource和UrlResource和ClassPathContextResource三种
4. ConfigurableApplicationContext 可配置化的上下文
5. LifeCycle 生命周期对象
6. ListableBeanFactory 具有列表能力的bean工厂
7. HierararchicalBeanFactory 具有层级关系能力bean工厂
8. ApplicationEventPublisher 可以发布事件的类
9. ResourcePatternResolver 资源模式处理器(根据路径获取解析出对应的资源)
10. MessageSource 国际化信息
从图一可以看出一个Spring应用上下文具备的能力:
1. BeanFactory bean工厂的能力
2. ResourceLoader 资源加载的能力
3. Lifecycle 生命周期的能力
4. MessageSource 国际化的能力
5. DisposableBean 销毁bean的能力
二、类成员变量介绍
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected final Log logger; // 日志
private String id; // 实例化ID
private ApplicationContext parent; // 父上下文
private final List beanFactoryPostProcessors; // Bean工厂的后置处理器
private String displayName; // 别名
private long startupDate; // 启动时间
private boolean active; // 是否活跃
private final Object activeMonitor; // 活跃监听器(锁)
private final Object startupShutdownMonitor; 启动关闭监听器(锁)
private Thread shutdownHook; // 关闭Hook
private ResourcePatternResolver resourcePatternResolver; // 资源模式解析器
private MessageSource messageSource; // 国际化信息
private ApplicationEventMulticaster applicationEventMulticaster; // 事件广播器
private List applicationListeners; // 应用监听器
三、启动refresh方法
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor; // 启动关闭监听器(锁)
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh(); // 准备刷新
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 获取刷新过的bean工厂
this.prepareBeanFactory(beanFactory); // 注册可能的BeanPostProcessors
try {
this.postProcessBeanFactory(beanFactory); // 修改上下文内部bean工厂当他被初始化之后
this.invokeBeanFactoryPostProcessors(beanFactory); // 调用执行beanFactory后置处理器
this.registerBeanPostProcessors(beanFactory); // 注册Bean后置处理器
this.initMessageSource(); // 初始化国际化处理器
this.initApplicationEventMulticaster(); // 初始化应用事件广播器
this.onRefresh(); // 刷新 交给子类去处理
this.registerListeners(); // 注册监听器
this.finishBeanFactoryInitialization(beanFactory); // 完成bean工厂初始化 (非延迟加载的实现)
this.finishRefresh(); // 完成刷新(发布对应的事件 上下文启动完成)
} catch (BeansException var5) {
beanFactory.destroySingletons(); // 销魂所有的单例bean
this.cancelRefresh(var5); // 取消刷新
throw var5; // 抛出异常
}
}
}
四、继承AbstrctGenericApplicationContext的两个核心基类: GenericApplicationContext 和 AbstractRefreshableApplicationContext,其余上下文基本上都是基于继承这两个其中之一进行扩展的。
GenericApplicationContext 泛型上下文(Springboot 采用的这个)
特点: 灵活
参考: https://www.jianshu.com/p/524d62ee91fb
GenericApplicationContext ctx = new GenericApplicationContext();
//使用XmlBeanDefinitionReader
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
//加载ClassPathResource
xmlReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(ctx);
propReader.loadBeanDefinitions(new ClassPathResource("otherBeans.properties"));
//调用Refresh方法
ctx.refresh();
//和其他ApplicationContext方法一样的使用方式
MyBean myBean = (MyBean) ctx.getBean("myBean");
AbstractRefreshableApplicationContext (SpringMvc用的这个)
例如Springmvc(XmlWebApplicationContext)
loadBeanDefinitions方法
XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(configLocation)
==> doLoadBeanDefinitions(InputSource inputSource, Resource resource)
==> BeanDefinitionDocumentReader.registerBeanDefinitions(Document var1, XmlReaderContext var2)
==> {
...
this.preProcessXml(root);
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
}
五. ClassPathBeanDefinitionScanner 介绍
@ComponentScan和<context:component-scan/>最终使用的包扫描都是该类,也体现spring代码的复用性很强。
<context:component-scan/>的代码流程
<context:component-scan/>对应
ContextNamespaceHandler.ComponentScanBeanDefinitionParser
==> ClassPathBeanDefinitionScanner.scan(basePackages)
@ComponentScan流程,核心在于ConfigurationClassPostProcessor(处理@Configuration)这个BeanFactory后置处理器
Springmvc和Springboot注册ConfigurationClassPostProcessor方式不同,
先看Springmvc,Springmvc入口还是<context:component-scan/>,
下面看调用链
ContextNamespaceHandler.ComponentScanBeanDefinitionParser
==> ClassPathBeanDefinitionScanner.scan(basePackages)
==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);(重点核心)
==> registerPostProcessor(new RootBeanDefinition(ConfigurationClassPostProcessor.class))
Springboot 的入口则是AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory)
下面看调用链
AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory)
==> new AnnotatedBeanDefinitionReader(this)
// 和SpringMvc一样都会到这一步
==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
==> registerPostProcessor(new RootBeanDefinition(ConfigurationClassPostProcessor.class))
上面重要的两个方法
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)(处理很多注解@Autowire @Resoure等等)和 ConfigurationClassPostProcessor.class
先只看ConfigurationClassPostProcessor,这个类使用是用于处理类上有@Configuration注解
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
==> processConfigBeanDefinitions(registry)
==> ConfigurationClassParser.parse(candidates)
==> processConfigurationClass(ConfigurationClass configClass)
==> @Conditional == >if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) return
==> doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
{
@Component ==> processMemberClasses(configClass, sourceClass);
@PropertySource ==> processPropertySource(AnnotationAttributes propertySource);
@ComponentScan ==> ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) ==> ClassPathBeanDefinitionScanner.doScan(String... basePackages)
@Import ==> processImports(configClass, sourceClass, getImports(sourceClass), true);
@ImportResource ==> ConfigurationClass.addImportedResource(resolvedResource, readerClass);
@Bean ==> ConfigurationClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
Register default methods on interfaces implemented by the configuration class ==> processInterfaces
}
// 对于ComponentScanAnnotationParser.class
ComponentScanAnnotationParser.parse()
==> ClassPathBeanDefinitionScanner.scan()
可以看到最终@ComponentScan交给ClassPathBeanDefinitionScanner去处理进行包扫描,spring代码的复用性是很强的,这也是值得去学习的地方。
六. aware的实现
包括ApplicationContextAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware BeanFactoryAware,
主要交给ApplicationContextAwareProcessor 这个Bean后置处理器。
看代码
postProcessBeforeInitialization(Object bean, String beanName)
==> invokeAwareInterfaces {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
那么问题来了,ApplicationContextAwareProcessor是在那一步注入的呢,可以很轻松找到在AbstractApplicationContext的prepareBeanFactory中,见代码如下
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
...
}
由于AbstractApplicationContext是基类,Springmvc和Springboot是一样的方式。
七.各个注解的实现原理(主要就是上面的AnnotationConfigUtils)
核心类ClassPathBeanDefinitionScanner.scan(String... basePackages)
/**
* Perform a scan within the specified base packages.
* @param basePackages the packages to check for annotated classes
* @return number of beans registered
*/
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 扫描注入@component的派生注解
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return this.registry.getBeanDefinitionCount() - beanCountAtScanStart;
}
@component的派生性
@Repository @Controller @Service @Repository @Configuration的支持如下方法
ClassPathBeanDefinitionScanner.doScan(String... basePackages)
==> findCandidateComponents(String basePackage)
==> scanCandidateComponents(basePackage)
==> isCandidateComponent 为true则添加。主要是Component的派生注解都为true
可能要问为什么, 那么答案在ClassPathScanningCandidateComponentProvider中
ClassPathScanningCandidateComponentProvider.registerDefaultFilters()
==> this.includeFilters.add(new AnnotationTypeFilter(Component.class));
==> {
// 见AnnotationTypeFilter的match方法
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
return metadata.hasAnnotation(this.annotationType.getName()) ||
(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
}
// isCandidateComponent 方法
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return true;
}
}
return false;
}
}
@其他相关注解
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
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);
// 向容器中增加@Configuration相关的处理器ConfigurationClassPostProcessor
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、@Value、@Inject相关的处理器AutowiredAnnotationBeanPostProcessor
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));
}
//在支持JSR-250条件下注册javax.annotation包下注解处理器,包括@PostConstruct、@PreDestroy、@Resource注解等
// 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));
}
//支持jpa的条件下,注册org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor处理器,处理jpa相关注解
// 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));
}
// 增加@EventListener相关处理器
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));
}
// 注册支持@EventListener注解的处理器, 也就是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;
}
@Configuration 注解
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 和 postProcessBeanFactory
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)==> processConfigBeanDefinitions(registry) ==>
ConfigurationClassParser.parse(candidates) ==>
processConfigurationClass(ConfigurationClass configClass)
==> @Conditional == >if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) return
==> doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
{
@Component ==> processMemberClasses(configClass, sourceClass);
@PropertySource ==> processPropertySource(AnnotationAttributes propertySource);
@ComponentScan ==> ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) ==> ClassPathBeanDefinitionScanner.doScan(String... basePackages)
@Import ==> processImports(configClass, sourceClass, getImports(sourceClass), true);
@ImportResource ==> ConfigurationClass.addImportedResource(resolvedResource, readerClass);
@Bean ==> ConfigurationClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
Register default methods on interfaces implemented by the configuration class ==> processInterfaces
}
==> add(ImportAwareBeanPostProcessor)
八 Springmvc 包扫描加载流程总结(XmlWebApplicationContext )
XmlWebApplicationContext ==> {
getConfigLocation(String location) 默认"/WEB-INF/applicationContext.xml"
loadBeanDefinitions 加载xml ==> 不同的节点对应不同的NamespaceHandler处理
{
<context:component-scan> ==> ContextNamespaceHandler
==> ComponentScanBeanDefinitionParser.parse
==> ClassPathBeanDefinitionScanner.scan(String[] basePackages)
==> {
==> doScan(basePackages) 扫描@Component派生注解 (@Component @Repository @Controller @Service @Repository @Configuration)并注入IOC容器
==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry) 扫描
{
==> 1.向容器中增加@Configuration相关的处理器ConfigurationClassPostProcessor
==> 2.增加@Autowired、@Value、@Inject相关的处理器 AutowiredAnnotationBeanPostProcessor
==> 3.在支持JSR-250条件下注册javax.annotation包下注解处理器,包括 @PostConstruct、@PreDestroy、@Resource注解等
==> 4.支持jpa的条件下,注册 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
处理器,处理jpa相关注解
==> 5.增加@EventListener相关处理器
==> 6.注册支持@EventListener注解的处理器, 也就是DefaultEventListenerFactory实例
}
}
}
}
}
Springboot 包扫描过程(web)
// 主要分为两部
//1.将启动类注册为bean
//2.根据已注册bean(启动类)注解展开进行扩展。
SpringApplication.run(Class<?> primarySource, String... args)
==> createApplicationContext()(web是AnnotationConfigServletWebServerApplicationContext,ConfigurationClassPostProcessor.class, 见上面AnnotationConfigServletWebServerApplicationContext分析)
//
==> prepareContext
==> load(Object source)
// 将启动类注入到bean中 第一步已完成
==> this.annotatedReader.register(source);
// 下面是第2步
==> refreshContext()
==> AbstractApplicationContext.refresh()
==> ConfigurationClassPostProcessor(上面已分析)
ConfigurationClassPostProcessor会处理第一步得到的bean,由于@SpringApplication包含@ComponentScan,而当ComponentScan的value为null是默认会扫描当前包下的所有包(分析见ComponentScanAnnotationParser)
ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) {
...
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
ps:写的都是自己的见解,能力有限,难免会有错误,仅做笔记以及抛砖引玉之用。