作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
前言
前面写了一些netty
的源码解析,虽然覆盖不了所有的内容,但是大部分核心的内容都讲到了,主要还是要自己去看,去理解,然后写点小demo
,领会netty
的设计意图,为什么能高性能,从线程的分工明确,多路复用到内存分配的分而治之,让多线程之间减少竞争,让内存使用效率提高,等等一些思想。现在想再分析下Spirng 5.2.1.RELEASE
的源码,虽然这个很复杂,但是我们还是可以大致了解一些原理,对以后使用和问题定位都有所帮助,而且还可以学到一些思想,一些处理方法,一些设计模式等等。我们主要是研究注解使用的一些原理。
简单注解例子
首先我们创建一个配置类MyConfig
:
@Configuration
public class MyConfig {
}
然后写一个测试方法,方便我们调试:
@Test
public void BeanDefinitionRegistryPostProcessorTest0() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
}
啥都不干,就分析他对配置类做了什么。
简单思考
先不看源码,我们自己思考下我们把一个配置类放进去,他可能会做点什么。假设我们都用过Spring
,哪怕最简单的那种,很明显我们可以猜到,他里面应该是对我们注解@Configuration
的类进行了解析,分析他里面有点什么,然后进行相应的处理。确实大致思路就这样,但是具体就比较复杂了,我们还是看源码慢慢分析吧。
AnnotationConfigApplicationContext注解配置上下文
先看下大致创建了什么
首先我们看名字只知道他是注解配置的上下文,也就是一个环境,那环境里面应该有好多东西,可以处理我们传进去的类。我们刚才调用的构造方法就是这个:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
首先他先创建了一个DefaultListableBeanFactory
,这个就是后面一直要用的bean
工厂,里面放着所有和bean
相关的东西,比如bean
定义,bean后置处理器等等,其实spring的思想就是把你给他的类都需要一个bean
定义来描述,这样才可以进行处理。然后再创建AnnotatedBeanDefinitionReader
和ClassPathBeanDefinitionScanner
,一个是注解的bean
定义读取器,一个是bean
定义的扫描器。这里要注意ClassPathBeanDefinitionScanner
其实是提供给用户用的,并不是他内部使用,内部后面他会再创建一个来用。我们先来看下AnnotatedBeanDefinitionReader
创建做了什么。
AnnotatedBeanDefinitionReader读取器
看这个构造方法,传入的是一个BeanDefinitionRegistry
类型,就是可以注册bean
定义的,内部要注册就需要用到。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
getOrCreateEnvironment获得或者创建环境
如果BeanDefinitionRegistry
是EnvironmentCapable
的话就可以直接获取,否则就创建一个标准环境,其实就是获取一些系统的变量。比如可以配置dev
环境,test
环境,online
环境等等。
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();
}
return new StandardEnvironment();
}
AnnotatedBeanDefinitionReader构造方法
对BeanDefinitionRegistry
进行了保存和把environment
封装进了ConditionEvaluator
,ConditionEvaluator
可以理解成一个条件过滤器,与@Conditional
有关,如果有了这个注解,就先判断条件成不成立,不成立的话有些操作就不做了。
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);
}
重要属性
另外有三个属性后面会用到,比如bean
的名字生成器BeanNameGenerator
,可以自定义怎么生成,默认是简单类名首字母小写,还有一个是范围注解的解析器ScopeMetadataResolver
,解析出范围,是单例,还是原型,另一个就是条件评估器了ConditionEvaluator
:
private final BeanDefinitionRegistry registry;
//类名生成器
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
//socpe注解解析器
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
//条件评估器
private ConditionEvaluator conditionEvaluator;
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)注册注解配置处理器
这个一看方法就知道要加一些处理器,来处理我们的注解,也就是说,spring
有些内部的处理器需要注册进来,这里可以想到spring
应该是为了统一处理处理器,所以也是按注册,处理这样的流程来,无论是自己内部的,还是用户自定义的,我们来看看里面是怎么做的。
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
主要流程就是获取DefaultListableBeanFactory
,然后注册AnnotationAwareOrderComparator
顺序比较器,排序用的,ContextAnnotationAutowireCandidateResolver
自动装配解析器,解析自动装配相关配置用。然后创建一些后置处理器的bean
定义,内部一般用RootBeanDefinition
来定义,比如这个类ConfigurationClassPostProcessor
,他是前面配置类处理的关键,所以这里先添加bean
定义,还有AutowiredAnnotationBeanPostProcessor
,处理自动装配的,另外还有EventListenerMethodProcessor
和DefaultEventListenerFactory
,CommonAnnotationBeanPostProcessor
暂时不讲,后面用到会说。
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());//设置自动装配解析器
}
}
//创建BeanDefinitionHolder集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//设置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));
}
//自动装配注解处理器
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;
}
AnnotationConfigUtils的registerPostProcessor注册后置处理器
注册后置处理器,其实是注册对应的bean
定义,对于一些内部处理器的bean
定义,会设置角色属性setRole
,然后向registry
里注册beanName
和bean
定义,最后封装成BeanDefinitionHolder
返回。
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);//注册进registry
return new BeanDefinitionHolder(definition, beanName);
}
GenericApplicationContext的registerBeanDefinition注册bean定义
可以看到,这里出现了beanFactory
,就是我们开始获得的DefaultListableBeanFactory
,注册bean
定义是交给他的。
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
DefaultListableBeanFactory的registerBeanDefinition注册bean定义
其他非核心的暂时略过了,剩下就两行,最终是把他放入ConcurrentHashMap
中,名字放入ArrayList
中。放在map
里是为了后面可以方便映射获取,名字在list
中则是为了方便获取遍历。
...
this.beanDefinitionMap.put(beanName, beanDefinition);//名字和bean定义对应
this.beanDefinitionNames.add(beanName);//名字
...
BeanDefinitionHolder封装bean定义而已
这个类其实就是对beanName
和bean
定义和别名做了封装:
最后注解配置处理器注册完成,注册了比较器和解析器,注册了注解处理器bean
定义:
可以看到,内部的bean
定义全部都是用RootBeanDefinition
,关于bean
定义的类型后面会说,先了解就行。至此读取器创建完成,其实就是注册了需要处理注解的处理器bean
定义,此时还没有创建bean
哦。后面ConfigurationClassPostProcessor
发挥着很大的作用,用来解析配置类。后面我们要先了解下spring
里的bean
定义到是定义什么。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。