Spring源码解析之BeanFactoryPostProcessor(一)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Spring源码解析之BeanFactoryPostProcessor(⼀)
BeanFactoryPostProcessor
在前⾯⼏个章节,笔者有介绍过BeanFactoryPostProcessor接⼝,在spring在解析BeanDefinition之后,根据BeanDefinition初始化bean之前,会回调我们编写的BeanFactoryPostProcessor实现类并调⽤postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)⽅法,spring会通过这个⽅法传⼊⼀个ConfigurableListableBeanFactory对象,我们可以对这个bean⼯⼚对象新增或修改BeanDefinition。

spring初始化bean⼀个典型的流程,就是根据我们标记在类上的@Component⽣成⼀个BeanDefinition,BeanDefinition中包含这个类的class对象,然后根据class对象⽣成实例。

如果我们编写两个Service:UserService和OrderService,并在类上标注@Component,再编写⼀个BeanFactoryPostProcessor接⼝,在接⼝中我们拿到UserService的BeanDefinition,并修改class为OrderService,那么我们从spring容器中获取userService这个bean,它的类型是UserService呢还是OrderService呢?来看下⾯的⽰例:
package org.example.service;
import ponent;
@Component
public class OrderService {
}
package org.example.service;
import ponent;
@Component
public class UserService {
}
在Test1BeanFactoryPostProcessor类中,我们获取userService的BeanDefinition,并打印它的class对象,这⾥应该是UserService,然后我们再设置BeanDefinition的class为OrderService
Test1BeanFactoryPostProcessor.java
package org.example.service;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import ponent;
@Component
public class Test1BeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
ScannedGenericBeanDefinition beanDefinition = (ScannedGenericBeanDefinition) beanFactory.getBeanDefinition("userService");
System.out.println("UserService beanDefinition class:" + beanDefinition.getBeanClass());
beanDefinition.setBeanClass(OrderService.class);
}
}
MyConfig.java
package org.example.config;
import ponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("org.example.service")
public class MyConfig {
}
测试⽤例:
@Test
public void test01() {
ApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("userService class:" + ac.getBean("userService").getClass());
}
运⾏结果:
UserService beanDefinition class:class erService
userService class:class org.example.service.OrderService
可以看到,spring容器会回调我们编写的bean⼯⼚后置处理器BeanFactoryPostProcessor实现类Test1BeanFactoryPostProcessor ,在回调⽅法中,我们可以从bean⼯⼚获取spring容器已经解析的UserService对应的BeanDefinition对象,打印这个BeanDefinition对象的class对象也确实是UserService的class对象,之后我们修改UserService对应的BeanDefinition的class对象为OrderService的class对象,之后我们从spring容器获取beanName为userService的bean可以看到bean的实现类已经被替换成OrderService对象。

这也验证笔者之前所说的⼀个事实,BeanFactoryPostProcessor的回调时机,是在spring容器将类解析为BeanDefinition之后,及根据BeanDefinition⽣成bean之前。

当然,这段代码在实际开发中意义并不⼤,这⾥只是为了揭露spring的实现。

那么笔者这⾥有个疑问,spring是在何时解析BeanDefinition?何时回调BeanFactoryPostProcessor?何时初始化bean?回顾测试⽤例
test01的两⾏代码,我们可以确定,前⾯的解析、回调、初始化⼀定是在test01⾥两句代码的某⼀句完成的,那么究竟是那⼀句呢?是创建应⽤上下⽂,还是打印userService对应的class对象呢?
为了定位上⾯的问题,我们对UserService和OrderService稍作修改,我们在两个类的构造函数中增加打印:
public class UserService {
public UserService() {
System.out.println("UserService init...");
}
}
public class OrderService {
public OrderService() {
System.out.println("OrderService init...");
}
}
测试⽤例:
@Test
public void test02() {
ApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
}
运⾏结果:
UserService beanDefinition class:class erService
OrderService init...
OrderService init...
结果打印了两次OrderService构造函数的内容,⼀次spring根据OrderService对应的BeanDefinition进⾏初始化,⼀次是我们修改userService对应的BeanDefinition的class为OrderService,spring根据class进⾏初始化。

⽽test02只有⼀⾏初始化应⽤上下⽂的代码,⾄此我们可以确定,spring的解析BeanDefinition、回调BeanFactoryPostProcessor、初始化bean都在初始化应⽤上下⽂完成。

当然,spring的应⽤上下⽂实现,有:AnnotationConfigApplication、ContextClassPathXmlApplicationContext……等等,但⼤部分的应⽤上下⽂实现都是在初始化的时候完成解析BeanDefinition、回调BeanFactoryPostProcessor、初始化bean这三步。

我们在调⽤应⽤上下⽂的构造函数AnnotationConfigApplicationContext(Class<?>... componentClasses)时,这个函数内部会先调⽤默认的⽆参构造⽅法,初始化reader和scanner两个对象。

调⽤完默认构造⽅法后,接着调⽤register(Class<?>... componentClasses)将我们的配置类注册进reader,这⼀步就会根据配置类⽣成BeanDefinition并注册进spring容器,之后调⽤继承⾃⽗类AbstractApplicationContext的refresh()⽅法。

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
……
}
于是我们进⼊到AbstractApplicationContext的refresh()⽅法,这个⽅法⾸先在<1>处调⽤obtainFreshBeanFactory()获取⼀个beanFactory对象,在<2>、<3>会把beanFactory作为参数传⼊其他⽅法,<2>处我们单看⽅法名invokeBeanFactoryPostProcessors可以知道这⾥是调⽤BeanFactoryPostProcessor接⼝,我们之前编写的BeanFactoryPostProcessor实现类,就是在<2>处进⾏回调。

<3>处单看⽅法名不太好理解,但如果看注释就可以知道,初始化“剩余且⾮懒加载”的单例对象,换⾔之:我们的dao、service、controller都是在这⼀层完成bean的初始化以及属性注⼊。

这⾥的“剩余”很有意思,当我们基于spring框架进⾏开发,⼤部分的bean都是单例对象,包括我们之前的配置类(MyConfig)、BeanFactoryPostProcessor在spring容器中都会有对应的BeanDefinition和bean,我们知道要调⽤⼀个类的⽅法,⾸先要有那个类的对象,在<2>处的invokeBeanFactoryPostProcessors可以回调我们编写的BeanFactoryPostProcessor实现类,说明在<2>处就已经进⾏⼀部分bean的初始化了,这部分bean就包含了BeanFactoryPostProcessor的实现类。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
……
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
……
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//<1>
……
try {
……
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);//<2>
……
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//<3>
……
}
catch (BeansException ex) {
……
}
finally {
……
}
}
}
……
}
我们总结⼀下,当我们调⽤AnnotationConfigApplicationContext(Class<?>... componentClasses)构造函数时,会先初始化reader和scanner 两个对象,然后将配置类注册到reader后,再调⽤refresh()进⾏BeanDefinition的解析、单例bean的实例化。

现在,我们来逐⾏分析AnnotationConfigApplicationContext(Class<?>... componentClasses)这个构造函数,⾸先这个构造函数会调⽤默认构造函数,进⾏reader和scanner的初始化,AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner接受⼀个BeanDefinitionRegistry接⼝类型的参数,⽽AnnotationConfigApplicationContext本⾝则实现了BeanDefinitionRegistry接⼝。

public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
从接⼝名BeanDefinitionRegistry本⾝我们可以知道,这个接⼝是⽤来注册BeanDefinition,⽽接⼝所要求的实现,从上⾄下允许我们建议beanName和BeanDefinition的映射关系、根据beanName移除BeanDefinition,根据beanName获取BeanDefinition、获取所有BeanDefinition对应的beanName,获取BeanDefinition的数量,判断beanName是否已被使⽤。

BeanDefinition之于beanName就如bean之于beanName⼀样,⼀个BeanDefinition⾄少有⼀个beanName,同理⼀个bean⾄少有⼀个beanName,因为BeanDefinition和bean都可以有别名。

public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
}
AnnotatedBeanDefinitionReader之所以要传⼊⼀个BeanDefinitionRegistry进⾏初始化,是因为在初始化AnnotatedBeanDefinitionReader 对象时会把⼀些基础BeanDefinition注册到BeanDefinitionRegistry,因为AnnotationConfigApplicationContext这个类本⾝就实现了BeanDefinitionRegistry接⼝,所以AnnotatedBeanDefinitionReader会把BeanDefinition注册到AnnotationConfigApplicationContext,spring容器可以根据这些基础的BeanDefinition初始化⼀些基础组件,这些组件在spring容器同样作为bean对象⽽存在,这些基础组件有的可以根据我们给定的类路径将我们的类解析为BeanDefinition,有的可以根据@Autowired、
@Inject、@Resource注解注⼊⼀个bean所依赖的bean。

当把⼀个BeanDefinitionRegistry对象传给AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)构造函数创建reader对象时,在下⾯代码<1>处对象会⽤字段registry指向传⼊的BeanDefinitionRegistry对象,⽅便后续向BeanDefinitionRegistry对象注册BeanDefinition。

public class AnnotatedBeanDefinitionReader {
……
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
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;//<1>
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
……
}
之后会执⾏AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source)⽅法,这个⽅法就是先前说的会注册多个基础BeanDefinition到BeanDefinitionRegistry,可以看到这⾥会调⽤registerPostProcessor⽅法在BeanDefinitionRegistry建⽴beanName和BeanDefinition的映射。

public abstract class AnnotationConfigUtils {
……
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
……
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);//<1>
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));//<2>
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);//<3>
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));//<4>
}
// 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);//<5>
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));//<6>
}
// 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;
}
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);//<7>
return new BeanDefinitionHolder(definition, beanName);
}
……
}
代码<1>创建⼀个ConfigurationClassPostProcessor的BeanDefinition,这个类实现了BeanDefinitionRegistryPostProcessor接⼝,它会根据我们指定的扫描路径去扫描组件。

代码<3>创建⼀个AutowiredAnnotationBeanPostProcessor的BeanDefinition,这个类主要是⽤于注⼊标记了@Autowired和@Inject的属性。

代码<5>创建⼀个ConfigurationClassPostProcessor的BeanDefinition,这个类主要是⽤于注⼊标记了@Resource的属性。

在代码的<2>、<4>、<6>会调⽤registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String
beanName)将beanName和BeanDefinition注册到BeanDefinitionRegistry。

代码<7>处接收到registry、beanName、BeanDefinition会调⽤registry的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)⽅法,对beanName和BeanDefinition进⾏映射。

上⾯的registry是我们之前创建的AnnotationConfigApplicationContext对象,如果我们查看AnnotationConfigApplicationContext的registerBeanDefinition⽅法,会发现这个⽅法是继承⽗类GenericApplicationContext,⽽GenericApplicationContext⼜是使⽤代理模式,将registerBeanDefinition⽅法的⼯作交由同样实现了BeanDefinitionRegistry接⼝的DefaultListableBeanFactory类来完成。

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
……
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
……
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
……
}
下⾯,我们再来看看DefaultListableBeanFactory的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)⽅法:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** Whether to allow re-registration of a different definition with the same name. */
private boolean allowBeanDefinitionOverriding = true;
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** Map from bean name to merged RootBeanDefinition. */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/** Names of beans that have already been created at least once. */
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
……
public boolean isAllowBeanDefinitionOverriding() {
return this.allowBeanDefinitionOverriding;
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");//<1>
……
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {//<2>
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
……
this.beanDefinitionMap.put(beanName, beanDefinition);//<3>
}
else {//<4>
if (hasBeanCreationStarted()) {//<5>
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {//<6>
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
……
}
protected boolean hasBeanCreationStarted() {
return !this.alreadyCreated.isEmpty();
}
protected void markBeanAsCreated(String beanName) {//<7>
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
……
}
在<1>处判断beanName和beanDefinition都不为空,因为这两者只要有其⼀为空都是不符合常理的,我们不会指定⼀个bean的名字为null,⽽beanDefinition如果为null,那就更不会⽣成bean。

如果beanName已存在对应的beanDefinition,就会进⼊到<2>处的分⽀。

这⾥会调⽤isAllowBeanDefinitionOverriding()⽅法判断是否允许重载beanDefinition,isAllowBeanDefinitionOverriding()返回allowBeanDefinitionOverriding字段,这个字段默认为true,即允许beanName重复,会接着执⾏到<3>处,为beanName和新的beanDefinition在beanDefinitionMap建⽴映射关系。

如果beanName在beanDefinitionMap不存在映射,则会进⼊到分⽀<4>处。

到达<4>处的分⽀后,会先进⾏hasBeanCreationStarted()的判断,从这个⽅法名我们可以知道,这个是判断是否存已被创建的bean,⽽hasBeanCreationStarted()⽅法的实现也是⾮常简单的,如果alreadyCreated不为空则返回true,事实上,当spring创建⼀个bean 时,会调⽤<7>处的markBeanAsCreated(String beanName)⽅法,将beanName加⼊到alreadyCreated集合⾥。

如果spring容器中存在已创建的bean,在注册beanDefinition会进⼊到<5>处对beanDefinitionMap加上同步锁,然后在建⽴beanName 和beanDefinition在beanDefinitionMap的映射,并创建⼀个updatedDefinitions对象,将旧的beanDefinitionNames列表和新的beanName加⼊到updatedDefinitions,再更新beanDefinitionNames指向updatedDefinitions。

为什么spring会有这⼀步操作呢?因为
即便spring容器初始化完毕,程序开始提供服务,依旧可以向容器注册beanDefinition并获取对应的bean。

换句话说,你⽤spring写了个电商系统,电商系统可以⼀边向⽤户提供下单服务,⼀边注册beanDefinition并⽣成对应的bean,甚⾄可以多线程注册
beanDefinition⽣成bean,所以才要对beanDefinitionMap加上同步锁,⽽markBeanAsCreated(String beanName)⾥加上同步锁也是同样的道理。

如果在注册beanDefinition时spring容器还没有⽣成bean,则会调⽤<6>处的⽅法,这⾥并没有⽤synchronized来防⽌多线程并发注册,因为这个时候spring认为容器还没完全启动起来,不会有多个请求并发进⾏,所以不需要⽤分⽀<5>内的synchronized代码块来保证注册BeanDefinition的线程安全性,仅仅是简单的在beanDefinitionMap上建⽴beanName和BeanDefinition的映射,然后将新的beanName加⼊到beanDefinitionNames。

现在,我们来总结下,在我们⽤AnnotationConfigApplicationContext(Class<?>... componentClasses)创建ApplicationContext对象
时,AnnotationConfigApplicationContext会先调⽤默认⽆参构造⽅法,在⽆参构造⽅法中进⾏AnnotatedBeanDefinitionReader的初始
化,AnnotatedBeanDefinitionReader的构造参数需要传⼊⼀个BeanDefinitionRegistry的实现,BeanDefinitionRegistry是⽤来注册⼀些基础的beanDefinition,⽽AnnotationConfigApplicationContext类实现了BeanDefinitionRegistry接⼝,将⾃⾝对象作为参数传⼊到AnnotatedBeanDefinitionReader的构造函数初始化reader对象。

在创建AnnotatedBeanDefinitionReader对象的时候,会把ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor这些类构造成RootBeanDefinition并注册到BeanDefinitionRegistry。

然⽽,AnnotationConfigApplicationContext也并不是在⾃⾝完成beanName和BeanDefinition的映射关系,⽽是其⽗类GenericApplicationContext使⽤了代理模式在内部⽣成⼀个DefaultListableBeanFactory类型的引⽤,借助DefaultListableBeanFactory来完成beanName和BeanDefinition的映射建⽴。

DefaultListableBeanFactory在注册beanName和BeanDefinition的时候,会先判断beanName 和BeanDefinition是否为空,为空就要报错,如果都不为空,再判断beanName在DefaultListableBeanFactory中是否已存在对应的BeanDefinition,如果存在再判断是否允许重载?默认是允许重载。

如果已存在,且允许重载,则重新在DefaultListableBeanFactory的beanDefinitionMap建⽴映射,如果已存在却不允许重载,则抛出异常。

如果beanName在注册时不存在已对应的BeanDefinition,那就要分两步判断了,⼀种是spring容器已存在bean,另⼀种是还不存在bean,⾸先在AnnotatedBeanDefinitionReader内部注册RootBeanDefinition的时候,⾛的是不存在bean的分⽀,也就是简单的把beanName和BeanDefinition存到beanDefinitionMap,beanName加⼊到beanDefinitionNames集合。

如果是spring中已存在bean的情况,为了防⽌多线程进⾏BeanDefinition的注册,spring对beanDefinitionMap加上同步锁,在同步代码块中保存beanName和BeanDefinition在beanDefinitionMap上的映射,将beanName加⼊到beanDefinitionNames。

GenericApplicationContext实现了BeanDefinitionRegistry接⼝,GenericApplicationContext类中存在⼀个名为beanFactory的字段,类型是DefaultListableBeanFactory,在调⽤GenericApplicationContext实现⾃BeanDefinitionRegistry的⽅法,会转⽽调⽤DefaultListableBeanFactory对应的⽅法。

public interface BeanDefinitionRegistry extends AliasRegistry {
……
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
……
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
……
}
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
……
}
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
……
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
……
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanFactory.getBeanDefinition(beanName);
}
……
}
⽽DefaultListableBeanFactory类本⾝也实现了BeanDefinitionRegistry,这就是典型的代理模式。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
……
}
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { BeanDefinition bd = this.beanDefinitionMap.get(beanName);
……
return bd;
}
}。

相关文档
最新文档