- 一、容器的创建
- 二、读取器创建
- 三、扫描器创建
- 四、小结
- 五、补充
- 1.BeanPostProcessor
- 2.Spring容器中属性说明
下面从Spring容器的创建开始分析,逐步深入来探究Spring的源码。
入口函数:
public static void main(String[] args) {
// 创建容器
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
// 从容器中获取Bean
IndexDao dao = annotationConfigApplicationContext.getBean(IndexDao.class);
// 调用Bean的方法
dao.query();
}
这里要看一下AnnotationConfigApplicationContext
这个类的构造方法:
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
// 这里由于它有父类构造方法,故而先调用父类的构造方法,然后才会调用自己的构造方法
this();
register(annotatedClasses);
refresh();
}
因为需要调用父类的构造方法,所以看下AnnotationConfigApplicationContext
继承结构:
查看GenericApplicationContext
类,并查看其构造方法:
public GenericApplicationContext() {
// 创建一个DefaultListableBeanFactory工厂
this.beanFactory = new DefaultListableBeanFactory();
}
注:对于这个DefaultListableBeanFactory
,我们就可以把它当成一个Spring容器
下面要看一下AnnotationConfigApplicationContext
无参构造方法了,因为上面的构造方法中调用了this()
方法。
public AnnotationConfigApplicationContext() {
// 创建一个 AnnotatedBeanDefinitionReader读取器,
// 同时向容器中填加了6个Spring的后置处理器:BeanFactoryPostProcessor、BeanPostProcessor
this.reader = new AnnotatedBeanDefinitionReader(this);
// 可以用来扫描包或者类,继而转换成BeanDefinition,但实际上我们扫描包工作不是这个scanner对象来完成的
// 是spring自己new的一个ClassPathBeanDefinitionScanner
// 这里的scanner仅仅是为了能够让程序员在外部调用AnnotationConfigApplicationContext对象的scan方法
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这个无参的构造方法,初始化一个bean的读取器和扫描器。
从这地方可以看出,我们的入口程序可以换一种写法,代码如下:
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(AppConfig.class);
annotationConfigApplicationContext.refresh();
IndexDao dao = annotationConfigApplicationContext.getBean(IndexDao.class);
dao.query();
}
以上代码能看懂么?其实就是把带参数的构造函数中的两行代码提取出来了,直接调用了AnnotationConfigApplicationContext
无参构造函数。
读取器和扫描器创建的入口在AnnotationConfigApplicationContext
无参构造方法中,来看下面的代码:
this.reader = new AnnotatedBeanDefinitionReader(this);
注:此处的this为AnnotationConfigApplicationContext
,表示一个Registry
进入到AnnotatedBeanDefinitionReader
的构造函数中:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 调用两个参数的构造器,如下
this(registry, getOrCreateEnvironment(registry));
}
// 两个参数的构造器
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,
Environment environment) {
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 这地方很重要(☆☆☆☆☆)
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
下面来看下AnnotationConfigUtils
这个类的registerAnnotationConfigProcessors()
方法:
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
// 下面
registerAnnotationConfigProcessors(registry, null);
}
// registerAnnotationConfigProcessors方法
public static Set registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 这行就是验证传进来的registry是不是DefaultListableBeanFactory类型,第一部分已说明,是!!
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
// AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set beanDefs = new LinkedHashSet(8);
//BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型
// 1、org.springframework.context.annotation.internalConfigurationAnnotationProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 向registry中放入ConfigurationClassPostProcessor
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 往Set集合中加入ConfigurationClassPostProcessor
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 2、org.springframework.context.annotation.internalAutowiredAnnotationProcessor
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));
}
// 3、org.springframework.context.annotation.internalRequiredAnnotationProcessor
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 4、org.springframework.context.annotation.internalCommonAnnotationProcessor
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));
}
// 5、org.springframework.context.annotation.internalPersistenceAnnotationProcessor
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 6、org.springframework.context.event.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));
}
// 7、org.springframework.context.event.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;
}
在上面的代码中,创建了一个大小为8的Set集合,集合元素类型为:BeanDefinitionHolder
。
并把下面7个类定义成BeanDefinitionHolder
后添加到Set中,并返回。
-
ConfigurationClassPostProcessor.class
-
AutowiredAnnotationBeanPostProcessor.class
-
RequiredAnnotationBeanPostProcessor.class
-
CommonAnnotationBeanPostProcessor.class
(Bean生命周期回调方法) -
PersistenceAnnotationBeanPostProcessor.class
-
EventListenerMethodProcessor.class
-
DefaultEventListenerFactory.class
下图是debug断点后,看到的Set集合中的内容为6个,其中,PersistenceAnnotationBeanPostProcessor.class
这个类不符合要求,没有被添加。
这6个类要么是BeanFactoryPostProcessor
的实现,要么是BeanPostProcessor
的实现。
上面的代码需要注意一下下面这行代码,下面来介绍一下这个registerPostProcessor()
方法
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
AnnotationConfigUtils.registerPostProcessor()
方法如下:
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 向registry中注册BeanDefinition
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
其实搞清楚这个方法,就是要搞清楚BeanDefinitionRegistry
和BeanDefinitionHolder
是干嘛的。
BeanDefinitionRegistry
是个接口,里面定义了一些操作BeanDefinition
的方法,如下:
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
void removeBeanDefinition(String beanName);
BeanDefinition getBeanDefinition(String beanName) ;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
}
而这些方法的主要实现类如下,是不是有看到了熟悉的DefaultListableBeanFactory
下面要来看下DefaultListableBeanFactory
中的registerBeanDefinition()
:
其实Spring容器,底层就是一个ConcurrentHashMap
// 存放所有BeanDefinition的Map
private final Map beanDefinitionMap = new ConcurrentHashMap(256);
// 存放了所有BeanDefinition的名字,通过扫描进去的
private volatile List beanDefinitionNames = new ArrayList(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 先从beanDefinitionMap中,根据beanName去获取BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
} else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
BeanDefinitionHolder
类如下,就是对BeanDefinition
进行了再次封装。
public class BeanDefinitionHolder implements BeanMetadataElement {
private final BeanDefinition beanDefinition;
private final String beanName;
//…… 略
}
下面打一个断点在registerAnnotationConfigProcessors()
方法的return beanDefs;
语句,看下面两个集合中的内容。
beanDefinitionNames
是个 List。
beanDefinitionMap
是个Map。
到此处,读取器的创建就结束了。回想一下,到目前为止,做了哪些工作?
只是向Spring容器中添加了6个BeanDefinition
,需要注意的是:这6个BeanDefinition
是Spring 自己添加的,这6个BeanDefinition
的功能是什么呢???Spring不会平白无故的往容器中放多余的东西吧。
这里,只是完成了Class
类到BeanDefinition
的转变,但BeanDefinition
并没有实例化。
所以,这6个BeanDefinition
很重要,后面会讲解它们的作用。
从上文可以知道,扫描器创建的入口也在AnnotationConfigApplicationContext
无参构造函数中,来看下面的代码:
this.scanner = new ClassPathBeanDefinitionScanner(this);
这地方创建了一个ClassPathBeanDefinitionScanner
扫描器对象,通过层层的构造函数封装,调用到了下面的这个构造函数。这地方代码不重要,可以直接忽略。
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
对于这个这个ClassPathBeanDefinitionScanner
扫描器,只需要知道下面的内容:
这个扫描器可以用来扫描包或者类,继而将扫描到的类转换成BeanDefinition
,但是实际上我们扫描包工作不是这个scanner
对象来完成的!!!而是Spring自己new的一个ClassPathBeanDefinitionScanner
,后面的代码分析会讲到。
这里的scanner
仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext
对象的scan
方法。
到目前为止,Spring做了以下几部分工作:
- 创建了一个
DefaultListableBeanFactory
容器 - 创建一个
AnnotatedBeanDefinitionReader
读取器- 在创建读取器的过程中,向Spring容器中添加了6个Spring自己的
BeanDefinition
- 在创建读取器的过程中,向Spring容器中添加了6个Spring自己的
- 创建一个
ClassPathBeanDefinitionScanner
扫描器- 这个扫描器仅仅是为了让程序员能够在外部调用,Spring真正的扫描工作不是这个扫描器来完成的
BeanPostProcessor
是Spring框架提供的一个扩展类点,但Spring的扩展类点不止这一个。
通过实现BeanPostProcessor
接口,程序员就可插手Spring Bean
实例化的过程,在Bean
实例化之后、初始化之前执行,从而减轻了BeanFactory
的负担,值得说明的是这个接口可以设置多个,会形成一个列表,然后依次执行。
程序员自己定义的BeanPostProcessor
,只需要实现BeanPostProcessor
接口,然后加上@Component
注解,就可以自动被扫描并添加到Spring容器中,但是Spring框架默认的怎么办呢?
本文第二部分,在读取器创建的时候,Spring框架就默认创建了5个BeanPostProcessor
。这5个BeanPostProcessor
非常重要。
比如AOP
就是在Bean实例后期间将切面逻辑织入Bean实例中的,AOP
也正是通过BeanPostProcessor
和Spring容器建立起了联系。
下面看看Spring提供哪些默认的BeanPostProcessor
实现,前方高能!!!
因为高能,故而只是解释几个常用的:
-
ApplicationContextAwareProcessor,简写acap 作用:当应用程序定义的Bean实现
ApplicationContextAware
接口时注入ApplicationContext
对象 -
InitDestroyAnnotationBeanPostProcessor
作用: 用来处理自定义的初始化方法和销毁方法。
Spring中提供了3种自定义初始化和销毁方法分别是
-
通过@Bean指定init-method和destroy-method属性
-
Bean实现InitializingBean接口和实现DisposableBean
-
@PostConstruct、@PreDestroy
为什么spring通这三种方法都能完成对bean生命周期的回调呢?
可以通过InitDestroyAnnotationBeanPostProcessor的源码来解释
-
-
InstantiationAwareBeanPostProcessor
-
CommonAnnotationBeanPostProcessor
-
AutowiredAnnotationBeanPostProcessor
-
RequiredAnnotationBeanPostProcessor
-
BeanValidationPostProcessor
-
AbstractAutoProxyCreator
BeanDefinition
:简称bd,是对一个Bean
的描述。类比,在Java中,你要描述一个用户,你得定义一个User类,在Spring中,你要描述一个Bean
的话,就定义个BeanDefinition
。
beanDefinitionNames
:存在Bean
的名字
beanDefinitionMap
:存放Bean
的名字与BeanDefinition
的对应关系
AnnotatedBeanDefinitionReader
:
BeanDefinitionRegistry
:简称bdr,把一个BeanDefinition
放入到beanDefinitionMap
中。