目录
说明:《spring 5 核心原理》读书笔记
一,引入
Spring中管理注解bean的容器有两个,AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext。这两个是专门处理注解方式配置的容器,我们这里主要研究第一个,因为第二个是第一个的web版本,基本功能差不多。
generic---通用的
整体看一下这个类的结构:
方法分类:4个构造方法;3个registerBean();scan();register();
这里讲解的是常用的构造方法,传入一个配置类。还有传入一个包路径的扫描构造方法。
测试代码:
public class App
{
public static void main( String[] args )
{
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfig.class);
User user=(User)applicationContext.getBean("user");
user.setName("123");
System.out.println( user.getName() );
}
}
@Configuration
public class MainConfig {
@Bean
public User user(){
return new User();
}
}
从一个构造方法进去,传入的是一个Class对象,也就是配置类的Class对象。开始初始化父类,然后调用register()将配置类注册进去。
(注意)之前我一直以为spring解析配置类会和解析xml一样进行详细解析,但是这里错了,它是把这个配置类作为一个bean进行装载,什么是配置类,打上@Configuration 注解的,称为配置类。而这个注解内容是什么样子的?
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration { ... }
看到了把,里面有Component组件,说明这就是一个bean。所以,在配置类中的内部!配置的bean,据我查的资料,要在 【后置处理器PostPRocessor】中才进行分析。所以,这里我们先看注解bean是如何进行加载的,同样你这里可以不传入一个注解bean。你可以直接传入一个你想要注册的bean,也可以直接调用register(bean)然后refresh()。它有很多方法进行注入,注入方式五花八门。
( @Configuration详细参考链接:https://www.jianshu.com/p/721c76c1529c )
二,配置bean的加载
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses); //把配置类传进去了啊。
refresh();
}
// 1.this()
// 父类:GenericApplicationContext类的构造方法:初始化了BeanFactory容器
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
// 实例化reader和scanner
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
// 2.register() 注册自定义的配置类
public void register(Class<?>... annotatedClasses) {
this.reader.register(annotatedClasses);
}
在调用this()方法的时候,同时也会执行父类的无参构造方法,该方法中初始化了BeanFactory,他的默认实现类:DefaultListableBeanFactory类,里面包含了多个数据结构容器,用来存放类的信息。看一下该类的继承关系图:
2.1 reader初始化
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.registry = registry; //保存AnnotationConfigApplicationContext
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); //注册
}
可以看到AnnotationConfigApplicationContext引用了reader,而reader同时又引用了AnnotationConfigApplicationContext。
在注解Bean的读取器构造方法中,重点是这个注册方法registerAnnotationConfigProcessors(),注册配置类处理器,用来解析配置类中的bean的,而且注意这个工具类AnnotationConfigUtils类,后面会经常用到:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//1.获取GenericApplicationContext属性: 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());
}
}
// ================== 此处添加了7个Bean, 但是这里的返回值,并没有进行使用!========
//创建BeanDefinitionHolder集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// ConfigurationClassPostProcessor处理器
// 判断BeanFactory的容器里面是否有指定的beanName;没有则注册进去
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 注入beanDef到 容器中,返回beanDefHolder对象
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));
}
//
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));
}
// 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;
}
这里的Bean使用RootBeanDefinition类进行封装,用Object保存class对象。
然后调用registerPostProcessor()方法,将bean注册到容器中,并返回BeanDefinitionHolder对象。
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
// 设置角色
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册name,和bean定义
registry.registerBeanDefinition(beanName, definition);
// 封装bean定义,返回
return new BeanDefinitionHolder(definition, beanName);
}
最后调用的是beanFactory(实现类:DefaultListableBeanFacotory)的registry()方法,将BeanDefinition注册到容器中:
// 将bean 注册到IOC容器 beanFactory中。
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 校验beanDefinition
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// 判断BeanDefinition是否存在
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 如果该bean不可以重复加载,则抛出异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + existingDefinition + "] bound.");
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isWarnEnabled()) {
logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 注册
this.beanDefinitionMap.put(beanName, beanDefinition); //【放入】
}
else {
if (hasBeanCreationStarted()) {
// 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); //添加新bean name
this.beanDefinitionNames = updatedDefinitions; //更新本类 字段
if (this.manualSingletonNames.contains(beanName)) {
Set<String> 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);
}
}
这里首次出现了存放bean的具体容器:beanDefinitionMap;同时存放Bean名字的容器:beanDefinitionNames。
这里返回的BeanDefinitionHolder封装了三个属性:beanDefinition,beanName,aliases;
最后,beanFactory容器中存在6个bean:
【插入】BeanDefinition实现类的关系:
后面的解析配置类,会把BeanDifinition分为AnnotatedBeanDefinition(接口)的子类和AbstractBeanDefinition子类,而Generic是两者的子类。
2.2 Scanner初始化
实例化ClassPathBeanDefinitionScanner类,构造方法如下:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
// 五个属性值,BeanDefinitionRegistry registry保存的AnnotationConfigApplicationContext类
// 其他四个直接使用默认值初始化,还有一个Patterns待定
private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();
@Nullable
private String[] autowireCandidatePatterns;
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
private boolean includeAnnotationConfig = true;
注册拦截器,调用父类的方法,保存拦截和不拦截的规则:
protected void registerDefaultFilters() {
// 拦击规则添加:拦截Component注解
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
2.3 register()
注册我们编写的配置类;使用AnnotatedBeanDefinitionReader类中的register()方法进行注册
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass); //这是一个入口
}
}
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null); //入口
}
本来的register只是入口,现在要调用reader的register方法,我们可以看一下这个reader是什么情况:AnnotatedBeanDefinitionReader reader;这个类是一个独立的类,没有继承,也没有子类。
看一下这类的结构:
它的功能是registerBean()跳转道doRegisterBean()。它有几个成员。下面P标注的。这几个成员应该都是分析这个类的工具。我们看一下方法执行流程
继续分析,来到doRegisteBean()方法
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//自定义的bean,使用AbstractBeanDefinition接口下的封装类
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); //注解+方法元数据 封装类,默认是注解元数据
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier); //为null
// 解析bean定义的作用域,若@Scpe("prototype"),则bean为原型类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName()); //设置 范围
//设置beanName,没有则自动使用手写字母小写
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理 注解Bean定义中的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 是否需要预加载
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));
}
}
}
// 是否需要定制化
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
// 添加beanName 封装为holder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 处理bean的作用域
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 向beanFacotry容器注册自定义Bean,和内部bean使用相同方法
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
注册 配置类bean定义类的基本步骤:
1.使用自定义Bean的专属AbstractBeanDefinition实现类,对bean的class对象进行封装。
2.使用AnnotationConfigUtils 的processCommon....处理注解bean定义类中通用的注解
3.使用AnnotationConfigUtils的applyScopedProxyMode()处理beanDef返回holder
4.通过BeanDefinitionReaderUtils向容器注册Bean。
我们分别来观察这四个功能的具体是实现:
2.3.1 对Class对象的封装
将我们自定义的配置类封装成为BeanDefinition类,之前在注册内部bean的时候提到过RootBeanDefinition类,此处自定义的Bean使用的AbstractBeanDefinition接口的实现类AnnotatedGenericBeanDefinitino类。
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
// 两个接口元数据
private final AnnotationMetadata metadata;
private MethodMetadata factoryMethodMetadata;
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
setBeanClass(beanClass); //跳转道了核心 AbstarctBeanDefintion类中
this.metadata = new StandardAnnotationMetadata(beanClass, true);
}
....
}
//父类AbstractBeanDefinition 将class对象保存
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
//StandardAnnotationMetadata类, 解析注解元数据
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
super(introspectedClass);
this.annotations = introspectedClass.getAnnotations(); //很简单,就是一个反射调用就ok了。
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
}
由于 doRegister方法,全部都在操作AnnotatedGenericBeanDefinition类,请回忆上面的BeanDefinition继承图!
回到doRegisterBean()方法,开始解析注解:(原理就是反射)
2.3.2 resolveScopeMetadata()
解析Scope 作用域,我们常用的就四种作用域。默认的是单列。注意传入的是配置类的beanDefinition形式
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
类:AnnotationScopeMetadataResolver中
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) { //实现了该接口
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; //强转
//工具类,解析 结果是map的子类
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
if (attributes != null) { //将解析结果,存放元数据中
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}
2.3.3 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd)
处理注解bean中的通用注解,什么通用注解,就是lazy是否懒加载,Primary是否优先调用,就是一些常用的注解。
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); //从元数据中获取
//@lazy
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
//@Peimary
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
//@DependsOn
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
if (abd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
absBd.setRole(role.getNumber("value").intValue());
}
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
absBd.setDescription(description.getString("value"));
}
}
}
2.3.4 applyScopedProxyMode()
将Annotation...BeanDefinition 这个对象abd进行封装,配上对应的beanName--->封装成为:BeanDefinitionHolder这个和xml方式的加载是一样的,然后又根据相应的作用域 创建相应的代理对象,这里我们看一下如何创建代理对象(这里就设计到了bean的生命周期,和代理模式,aop等等事情)(该方法还是在AnnotationConfigUtils类中)
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
//得到 name为 NO
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
return definition;
}
//获取scope注解的proxyMode属性值
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
//为注册的bean创建 相应模式的代理对象
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
观察一下,发现这里其实也是一个幌子,真正的创建应该是在return时调用的createScopeProxy方法里面。这里一顿追踪会发现在ScopedProxyUtil类中找到真正的执行方法:
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
BeanDefinitionRegistry registry, boolean proxyTargetClass) {
//获取源信息
String originalBeanName = definition.getBeanName();
BeanDefinition targetDefinition = definition.getBeanDefinition();
String targetBeanName = getTargetBeanName(originalBeanName);
// 创建代理
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
//疯狂给这个代理对象 设置属性
proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
proxyDefinition.setSource(definition.getSource());
proxyDefinition.setRole(targetDefinition.getRole());
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
}
else {
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
}
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
proxyDefinition.setPrimary(targetDefinition.isPrimary());
if (targetDefinition instanceof AbstractBeanDefinition) {
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
}
targetDefinition.setAutowireCandidate(false);
targetDefinition.setPrimary(false);
registry.registerBeanDefinition(targetBeanName, targetDefinition);
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
奇怪的是,这里返回的是一个BeanDefinitionHolder ,但是在doRrigster()方法中,并没有接收这个返回值。
2.3.5 注册配置bean
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
该方法和注册内部Bean使用同一个方法,不再重复讲诉。
参考链接:
https://www.cnblogs.com/cxuanBlog/p/11179439.html(注解使用)
https://segmentfault.com/a/1190000017413393?utm_source=tag-newest