本文的目的
- 基于源码快速的了解一个对象是怎么产生的
- 我们可以怎么对spring的生产过程进行干预
对象的一个大致创建流程
bean转成bd放入到bdMap中,然后根据bean的名称从bdMap中拿bd进行创建,创建的时候会经过一系列的后置处理器,最中返回我们需要创建的bean
最后会总结出来一张图来解释
构建测试用例
- 代码如下
@Test
public void registerBean() {
// 1 初始化上下文环境 AnnotationConfigApplicationContext
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//2 添加配置类
context.register(Config.class, NameConfig.class);
//3 执行工厂的刷新方法
context.refresh();
//4 调用getBean方法 获取对象
TestBean testBean = (TestBean) context.getBean("testBean");
assertEquals("foo", testBean.name);
}
@Configuration
static class Config {
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.name = "foo";
return testBean;
}
}
@Configuration
static class NameConfig {
@Bean
String name() {
return "foo";
}
}
由于篇幅原因,本章只解释第一步骤 初始化上下文环境 AnnotationConfigApplicationContext
初始化上下文环境都做了一下什么事?
当执行了 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
这行代码, 会执行初始化的构造方法;
根据继承关系 AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
可以看出,会先执行 GenericApplicationContext
的构造方法,然后再执行AnnotationConfigApplicationContext
的构造方法
执行GenericApplicationContext的构造方法
/**
* 创建一个 beanFactory
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
创建一个 DefaultListableBeanFactory
对象
/**
* Create a new DefaultListableBeanFactory.
*/
public DefaultListableBeanFactory() {
super();
}
super()
方法中在父类的实现
/**
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
//添加忽略依赖的接口 BeanNameAware
ignoreDependencyInterface(BeanNameAware.class);
//添加忽略依赖的接口 BeanFactoryAware
ignoreDependencyInterface(BeanFactoryAware.class);
//添加忽略依赖的接口 BeanClassLoaderAware
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
执行完构造方法后是创建了一个DefaultListableBeanFactory
对象,对象包含很多属性,简要列举下下边会用到的属性。
/** key是bean的名称value是BeanDefinition*/
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** bean名称的集合 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/**bean的后置处理器*/
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
执行AnnotationConfigApplicationContext本身的构造方法
/**
* 创建注解配置类型的额上下文 本身也是一个注册中心
* 会调用父类方法 创建 beanFactory
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
// 注解bean定义信息解析器
// 添加工厂的后置处理器 和bean的后置处理器
this.reader = new AnnotatedBeanDefinitionReader(this);
//扫描指定包下的bean转成bd
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这个构造方法很重要
首先是实例化一个AnnotatedBeanDefinitionReader
对象,这个对象的作用就是解析被注解的bean,转换成beanDefinition;还有就是向容器中添加beanFactory的后置处理器和bean的后置处理器。注意这个构造方法是需要传入一个 registry ,通过最开始的继承结构可以知道AnnotationConfigApplicationContext 也实现了BeanDefinitionRegistry接口
创建ClassPathBeanDefinitionScanner
对象,这个对象如果是采用的注解方式并且没有手动调用context.scan("org.springframework.context.xxx");
这个方法实际上是没有用的,看名称我们可以知道,这个对象主要是扫描ClassPath下的bean转换成BeanDefinition。但是实际在后边真正处理的时候会重新新建一个,在这次存在的意思就是类似与上边我们手动调用scan方法
所以接下来我们着重讲解AnnotatedBeanDefinitionReader
对象
当我们调用这个对象的构造方法的时候最终会进入org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
这个方法
代码如下
/**
* Register all relevant annotation post processors in the given registry.
*
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//获取 beanFactory 此处是 DefaultListableBeanFactory 看前边的继承关系
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//添加 排序的bean
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//用于确定特定的Bean定义是否符合特定的依赖项的候选者的策略接口。
//ContextAnnotationAutowireCandidateResolver这个是最全的一个策略接口可以处理Lazy
//此处处理的lazy不是懒加载,是懒处理
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// BeanDefinitionHolder 是对 bd 和bean 名称的一个封装
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//name=org.springframework.context.annotation.internalConfigurationAnnotationProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//添加 BeanDefinitionRegistryPostProcessor 类型的实现类 ConfigurationClassPostProcessor 也是 beanFactoryPostProcessor的实现类
// ConfigurationClassPostProcessor 这个类的作用很大 会把我们程序中需要加载的bean转乘bd从而被实例化成bean
//后边会着重讲解
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//org.springframework.context.annotation.internalAutowiredAnnotationProcessor
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//添加BeanPostProcessor类型的实现类 AutowiredAnnotationBeanPostProcessor 主要是解决属性自动装配问题
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)) {
//添加BeanPostProcessor类型的实现类 CommonAnnotationBeanPostProcessor 主要是处理类中的 PreDestroy ,PostConstruct ,Resource 这些注解
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;
}
这个方法的主要主要作用就是向给定的注册中心中加入beanFactory的后置处理器ConfigurationClassPostProcessor
(会在refresh中重点讲解)和一些bean的后置处理器比如 CommonAnnotationBeanPostProcessor
主要负责处理类中的 PreDestroy ,PostConstruct ,Resource 这些注解。
执行第二步向注册中心添加配置类
代码 context.register(Config.class, NameConfig.class);
方法最终调用 org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
/**
* Register a bean from the given bean class, deriving its metadata from
* class-declared annotations.
* @param beanClass the class of the bean
* @param instanceSupplier a callback for creating an instance of the bean
* (may be {@code null})
* @param name an explicit name for the bean
* @param qualifiers specific qualifier annotations to consider, if any,
* in addition to qualifiers at the bean class level
* @param definitionCustomizers one or more callbacks for customizing the
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0
*/
<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//传进来的类包装成 AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//是否需要跳过 一般不会
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//注册回到函数获取对象 一般没有
abd.setInstanceSupplier(instanceSupplier);
//解析作用域 如果没有指定 默认为单例 指定的化 根据注解上的信息获取值
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//设置作用域
abd.setScope(scopeMetadata.getScopeName());
//获得一个bean的名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理通用注解信息 Lazy Primary DependsOn Role Description 如果有这些属性 则取出赋值
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//qualifiers 类型的注解不为null的处理
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
//自定义函数 处理bd 一般没有
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//组装成 definitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//应用 ScopedProxyMode 判断需不需要生成代理 一般不会用 上边默认为 no
//@Scope(value = "prototype",proxyMode= ScopedProxyMode.TARGET_CLASS) 则每次调用时都会生成一个对象
//@Scope(value = "prototype") 同一个session 多次调用 产生同一个对象 不同的session调用每次都产生新的对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//放入到bdMap中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
到现在位置构造环境的前两步就讲完了,下一篇文章主要讲解org.springframework.context.support.AbstractApplicationContext#refresh
方法