Pre
接上文 Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition
我们分析了流程, 也从理论上描述了 普通对象 ----- BeanDefinition ------Bean对象之间的关联,提到了一个BeanDefinition的Map集合 (我们称之为 bdmap ,后面都用这个简称代替 ),
那从源码里面怎么体现出来bdmap 的呢?
本篇博文将带你一一掀开
Spring处理bdmap 的理念
因为这个bdmap 对应Spring太重要了,不仅要处理用户配置的扫描包下的bean,还有一点更重要Spring内置的bean 也需要依靠这个bdmap .
如果这个bdmap 完全交给开发者来处理,比如你把这个map中的数据给remove掉了,等等之类的不可信任的操作,结果可想而知,所以Spring封装了一些API,仅允许开发者通过Spring提供的API来修改bdmap .
源码分析
那我们来看下Spring是如何来封装的这个API呢?
接上文中的 BeanFactoryPostProcessor Bean工厂后置处理器
ConfigurableListableBeanFactory 这个 beanFactory对象 是Spring封装的用于提供给开发者修改BeanDefinition的一个接口类。
提供了 getBeanDefinition 方法
beanFactory.getBeanDefinition("artisan1");
ctrl + alt + b 打开实现类 DefaultListableBeanFactory
我们来看下 定义 beanDefinitionMap
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
Spring也是用的Map来存储的 ~
那我要看 spring是如何把BeanDefinition放到这个 beanDefinitionMap 中的,那我就需要重点观察 beanDefinitionMap 这个对象,Spring是在什么时候赋值的 .
我们知道了 DefaultListableBeanFactory 有个属性 是 beanDefinitionMap
先找DefaultListableBeanFactory
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
跟进去构造函数
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); refresh(); }
this() : 调用无参构造函数,会先调用父类GenericApplicationContext的构造函数 ,父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory . 本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner . scanner的用处不是很大,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的 .
register(componentClasses): 注册配置类 即 AppConfig.class
refresh() : 容器刷新,这个是最核心的方法。 很重要
回到this(),我们来看下源码
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {}
父类的构造函数
实例化DefaultListableBeanFactory
DefaultListableBeanFactory非常最重要, 主要就是用来生产和获得Bean的
接着子类的构造函数
this.reader = new AnnotatedBeanDefinitionReader(this); 初始化一个Bean读取器
this.scanner = new ClassPathBeanDefinitionScanner(this);初始化一个扫描器,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
继续看 new AnnotatedBeanDefinitionReader(this)
实例化建BeanDefinition读取器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { //注册了实现Order接口的排序器 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } //设置@AutoWired的候选的解析器 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); /** * 为我们容器中注册了解析我们配置类的后置处理器ConfigurationClassPostProcessor * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor */ 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 注解的处理器AutowiredAnnotationBeanPostProcessor * 名字叫: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)); } /** * 为我们容器中注册处理@Required属性的注解处理器RequiredAnnotationBeanPostProcessor * 名字叫: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)); } /** * 为我们容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor * 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)); } /** * 处理jpa注解的处理器org.springframework.orm.jpa.support.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)); } /** * 处理监听方法的注解解析器EventListenerMethodProcessor */ 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; }
主要工作
- 注册内置BeanPostProcessor 开天辟地的元勋Bean
- 注册相关的BeanDefinition
Step1 : this();
【初始化BeanFactory】
没有呢?我们知道实例化子类,父类也会被初始化,那往上找找吧
可以看到是在父类GenericApplicationContext中初始化的DefaultListableBeanFactory
这样的话,我们把断点打在下面一行 register(componentClasses)上,观察this 中的对象 如下
现在是有默认的Spring初始化的时候自己的BeanDefinition , 没有我们自己的bd ,那就继续走,看看这个beanDefinitionMap什么时候会发生变化~
register(componentClasses); 【注册bean】
先看结论
说明这一步就完成了 从 普通对象 (注册配置类)------- BeanDefinition ----------存入到 bdMap中的操作
接下来分析下核心源码
流程如下
如上 ,这个流程完成后, DefaultListableBeanFactory#beanDefinitionMap 就有了new AnnotationConfigApplicationContext(AppConfig.class)
入参中的 AppConfig.class 对应的Bean了
refresh();
那这个AppConfig配置的扫描包下的bean,什么时候初始化呢? 那就是refresh这个方法了 ,下文继续
先看一眼,结论
这个方法太重要了,一共有12个方法里面, 下篇博文 继续 分析