Spring 核心概念
引言
本文主要介绍 Spring 源码中使用到的一些核心类
1. BeanDefinition
BeanDefinition 表示 Bean 定义,BeanDefinition 中存在很多属性用来描述一个 Bean 的特点。比如:
class,表示 Bean 类型
scope,表示 Bean 作用域,单例或原型等
lazylnit:表示 Bean 是否是懒加载
initMethodName:表示 Bean 初始化时要执行的方法
destroyMethodName:表示 Bean 销毁时要执行的方法
还有很多。。。
在 Spring 中,我们经常会通过以下几种方式来定义 Bean:
<bean/>
@Bean
@Component(@Service,@Controller)
这些,我们可以称之申明式定义 Bean。我们还可以编程式定义 Bean,那就是直接通过 BeanDefinition,比如:
2. BeanDefinitionReader
接下来,我们来介绍几种在 Spring 源码中所提供的 BeanDefinition 读取器(BeanDefinitionReader),这些 BeanDefinitionReader 在我们使用 Spring 时用得少,但在 Spring 源码中用得多,相当于 Spring 源码的基础设施。
AnnotatedBeanDefinitionReader
BeanDefinition 读取器,可以直接把某个类转换为 BeanDefinition,并且会解析该类上的注解,比如:
注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description
XmlBeanDefinitionReader
可以解析<bean/>标签,将 xml 文件中定义的 bean 解析为 BeanDefinition
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner 是扫描器,但是它的作用和 BeanDefinitionReader 类似,它可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在 @Component 注解,那么就会把这个类解析为一个 BeanDefinition,比如:
3. BeanFactory
BeanFactory 表示 Bean 工厂,所以很明显,BeanFactory 会负责创建 Bean,并且提供获取 Bean 的 APl。\
而 ApplicationContext 是 BeanFactory 的一种,在 Spring 中的定义如下
首先,在 Java 中,接口是可以多继承的,我们发现 ApplicationContext 继承了 ListableBeanFactory 和 HierarchicalBeanFactory,而 ListableBeanFactory 和 HierarchicalBeanFactory 都继承至 BeanFactory,所以我们可以认为 ApplicationContext 继承了 BeanFactory,相当于苹果继承水果,宝马继承汽车一样,ApplicationContext 也是 BeanFactory 的一种,拥有 BeanFactory 支持的所有功能,不过 ApplicationContext 比 BeanFactory 更加强大,ApplicationContext 还基础了其他接口,也就表示 ApplicationContext 还拥有其他功能,比如 MessageSource 表示国际化,ApplicationEventPublisher 表示事件发布,EnvironmentCapable 表示获取环境变量,等等,关于 ApplicationContext 后面再详细讨论。
在 Spring 的源码实现中,当我们 new 一个 ApplicationContext 时,其底层会 new 一个 BeanFactory 出来,当使用 ApplicationContext 的某些方法时,比如 getBean0,底层调用的是 BeanFactory 的 getBean()方法。
在 Spring 源码中,BeanFactory 接口存在一个非常重要的实现类是:DefaultListableBeanFactory,也是非常核心的。
DefaultListableBeanFactory 是非常强大的,支持很多功能,可以通过查看 DefaultListableBeanFactory 的类继承实现结构来看
4. ApplicationContext
上面有分析到,ApplicationContext 是个接口,实际上也是一个 BeanFactory,不过比 BeanFactory 更加强大,比如:1.HierarchicalBeanFactory:拥有获取父 BeanFactory 的功能 2.ListableBeanFactory:拥有获取 beanNames 的功能 3.ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)4.EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)5.ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)6.MessageSource:拥有国际化功能
ApplicationContext 有两个比较重要的实现类:
1.AnnotationConfig ApplicationContext2.ClassPathXmlApplicationContext
4.1 AnnotationConfig ApplicationContext
ConfigurableApplicationContext:继承了 ApplicationContext 接口,增加了,添加事件监听器、添加 BeanFactoryPostProcessor、设置 Environment,获取 ConfigurableListableBeanFactory 等功能
AbstractApplicationContext:实现了 ConfigurableApplicationContext 接口
GenericApplicationContext:继承了 AbstractApplicationContext,实现了 BeanDefinitionRegistry 接口,拥有了所有 ApplicationContext 的功能,并且可以注册 BeanDefinition,注意这个类中有一个属性(DefaultListableBeanFactory beanFactory)
AnnotationConfigRegistry:可以单独注册某个为类为 BeanDefinition(可以处理该类上的 @Configuration 注解,已经可以处理 @Bean 注解),同时可以扫描
AnnotationConfig ApplicationContext:继承了 GenericApplicationContext,实现了 AnnotationConfigRegistry 接口,拥有了以上所有的功能
4.2 ClassPathXmlApplicationContext
它也是继承了 AbstractApplicationContext,但是相对于 AnnotationConfigApplicationContext 而言,功能没有 AnnotationConfig ApplicationContext 强大,比如不能注册 BeanDefinition
5. BeanPostProcessor
BeanPostProcess 表示 Bena 的后置处理器,我们可以定义一个或多个 BeanPostProcessor,比如通过一下代码定义一个 BeanPostProcessor:
一个 BeanPostProcessor 可以在任意一个 Bean 的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然,我们可以通过判断 beanName 来进行针对性处理(针对某个 Bean,或某部分 Bean)。我们可以通过定义 BeanPostProcessor 来干涉 Spring 创建 Bean 的过程。
6. BeanFactoryPostProcessor
BeanFactoryPostProcessor 表示 Bean 工厂的后置处理器,其实和 BeanPostProcessor 类似,BeanPostProcessor 是干涉 Bean 的创建过程,BeanFactoryPostProcessor 是干涉 BeanFactory 的创建过程。
7. FactoryBean
上面提到,我们可以通过 BeanPostPorcessor 来干涉 Spring 创建 Bean 的过程,但是如果我们想一个 Bean 完完全全由我们来创造,也是可以的,比如通过 FactoryBean:
通过上面这段代码,我们自己创造了一个 UserService 对象,并且它将成为 Bean。但是通过这种方式创造出来的 UserService 的 Bean,只会经过初始化后,其他 Spring 的生命周期步骤是不会经过的,比如依赖注入。有同学可能会想到,通过 @Bean 也可以自己生成一个对象作为 Bean,那么和 FactoryBean 的区别是什么呢?其实在很多场景下他俩是可以替换的,但是站在原理层面来说的,区别很明显,@Bean 定义的 Bean 是会经过完整的 Bean 生命周期的。
8.ExcludeFilter 和 IncludeFilter
这两个 Filter 是 Spring 扫描过程中用来过滤的。ExcludeFilter 表示排除过滤器,IncludeFilter 表示包含过滤器。比如以下配置,表示扫描 com.zhouyu 这个包下面的所有类,但是排除 UserService 类,也就是就算它上面有 @Component 注解也不会成为 Bean。
再比如以下配置,就算 UserService 类上没有 @Component 注解,它也会被扫描成为一个 Bean。
FilterType 分为:1.ANNOTATION:表示是否包含某个注解 2.ASSIGNABLE TYPE:表示是否是某个类 3.ASPECTJ:表示否是符合某个 Aspectj 表达式 4.REGEX:表示是否符合某个正则表达式 5.CUSTOM:自定义
在 Spring 的扫描逻辑中,默认会添加一个 Annotation TypeFilter 给 includeFilters,表示默认情况下 Spring 扫描过程中会认为类上有 @Component 注解的就是 Bean。
9. MetadataReader、ClassMetadata、Annotation Metadata
在 Spring 中需要去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数据,所以 Spring 中对类的元数据做了抽象,并提供了一些工具类。MetadataReader 表示类的元数据读取器,默认实现类为 SimpleMetadataReader
需要注意的是,SimpleMetadataReader 去解析类时,使用的 ASM 技术。为什么要使用 ASM 技术,Spring 启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在 Spring 启动时就把这些类全部加载进 JVM 了,这样不太好,所以使用了 ASM 技术。
版权声明: 本文为 InfoQ 作者【五公子】的原创文章。
原文链接:【http://xie.infoq.cn/article/0f7105dc3200ac4d0bece8e79】。文章转载请联系作者。
评论