Skip to content

Commit 4b192a7

Browse files
author
gnehcgnaw
committed
no message
1 parent 326eb77 commit 4b192a7

File tree

5 files changed

+65
-7
lines changed

5 files changed

+65
-7
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java

+14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
import org.springframework.lang.Nullable;
2323

2424
/**
25+
*
26+
* java ---- class ---- Class
27+
* spring ---- bean ----- BeanDefinition
2528
* BeanDefinition描述了一个bean实例, 它具备的属性和方法都是我们熟悉的,例如:
2629
* 类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等,
2730
* 其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,
@@ -38,6 +41,16 @@
3841
* 不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时有一个D方法,A如何决定该继承那一个呢?
3942
* 但接口不存在这样的问题,接口全都是抽象方法继承谁都无所谓,所以接口可以继承多个接口, (那到底继承了那个接口的方法呢??这估计只要研究了JVM才会知道。)
4043
*
44+
* BeanDefinition是一个接口,是一个抽象的定义,实际使用的是其实现类,如:
45+
* 1. {@link org.springframework.beans.factory.support.GenericBeanDefinition}
46+
* {@link org.springframework.context.annotation.ScannedGenericBeanDefinition}
47+
* {@link org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition}
48+
* 2. {@link org.springframework.beans.factory.support.RootBeanDefinition}
49+
* 3. {@link org.springframework.beans.factory.support.ChildBeanDefinition}
50+
*
51+
* 我们可以通过{@link ConfigurableListableBeanFactory#getBeanDefinition(String)}获取{@link BeanDefinition} 。
52+
*
53+
* Spring容器启动的过程中,会将类解析成Spring内部的BeanDefinition结构,并将BeanDefinition存储到一个叫DefaultListableBeanFactory中 。
4154
*
4255
* A BeanDefinition describes a bean instance, which has property values,
4356
* constructor argument values, and further information supplied by
@@ -117,6 +130,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
117130
String getParentName();
118131

119132
/**
133+
* 指定此bean定义的bean类名。
120134
* Specify the bean class name of this bean definition.
121135
* <p>The class name can be modified during bean factory post-processing,
122136
* typically replacing the original class name with a parsed variant of it.

spring-context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java

+34-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.springframework.util.Assert;
3232

3333
/**
34+
* 读取被加了注解的类
35+
*
3436
* Convenient adapter for programmatic registration of bean classes.
3537
* 方便的适配器,用于以编程方式注册Bean类。
3638
* 其核心方法是{@link AnnotationConfigApplicationContext#register}
@@ -220,8 +222,20 @@ public void registerBean(Class<?> beanClass, String name, Class<? extends Annota
220222
<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
221223
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
222224
//将传进来的普通的beanClass包装成AnnotatedGenericBeanDefinition,(这个地方可以打断点观看复制情况,以及AnnotatedGenericBeanDefinition类的继承情况。)
225+
/**
226+
* 根据指定的bean创建一个AnnotatedGenericBeanDefinition。
227+
*
228+
* 为什么创建的是一个AnnotatedGenericBeanDefinition呢?
229+
* 因为在之前传入的beanClass要求是被注解的类。
230+
*
231+
* 这个AnnotatedGenericBeanDefinition可以理解为一个数据结构,包含了类的其他信息,比如一些元信息,是scope,lazy等等。
232+
*/
223233
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
224-
//判断是否跳过注册,根据的是是否包含@Conditional,如果包含,要根据赋值情况去处理那些bean是要跳过不需要注册的。
234+
/**
235+
* 判断是否跳过解析,
236+
* 根据的是是否包含@Conditional,如果包含,要根据赋值情况去处理那些bean是要跳过不需要注册的。
237+
* springboot中去了解{@link Conditional}
238+
*/
225239
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
226240
return;
227241
}
@@ -231,14 +245,20 @@ <T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSuppli
231245
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
232246
//设置bean定义的作用域
233247
abd.setScope(scopeMetadata.getScopeName());
234-
/*
235-
* 生成bean名称,bean名称的生成规则是由专门接口的,它是BeanNameGenerator,假如我们想要改变spring对于bean名称的生成规则只需要实现BeanNameGenerator
236-
* 然后使用"annotationConfigApplicationContext.setBeanNameGenerator(myBeanNameGenerator);"进行设定。
248+
/**
249+
* 生成bean名称,bean名称的生成规则是由专门接口的,它是BeanNameGenerator,假如我们想要改变spring对于bean名称的生成规则只需要实现{@link BeanNameGenerator}
250+
* 然后使用{@link AnnotationConfigApplicationContext#setBeanNameGenerator(BeanNameGenerator)}进行设定。
237251
*/
238252
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
239253
//处理通用型的注解,这些直接包括@Lazy ,@Primary ,@DependsOn ,@Role ,@Description ,如果没有定义就赋予默认值
240254
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
241-
//判断注解是否有限定符,并赋值
255+
/**
256+
* 判断注解是否有其他限定符(@Primary ,@Lazy , @Qualifier),并赋值
257+
* 但是当前方法是不能被外部调用的,而且这个数组传入的也是null,所以,这段代码目前永远是执行不到的,除非通过反射机制,这段也许是为了后续扩展spring做准备的。
258+
* (不知道我这样理解对不对,难道这个后续会调用到吗,菜鸟是在不明白,此问题暂时放置【2019年11月19日15:58:38】)
259+
* //todo
260+
* 我在GitHub的spring-framework项目中issues中提出了疑问,不知道有没有为我解决:https://github.com/spring-projects/spring-framework/issues/24021
261+
*/
242262
if (qualifiers != null) {
243263
for (Class<? extends Annotation> qualifier : qualifiers) {
244264
if (Primary.class == qualifier) {
@@ -252,14 +272,22 @@ else if (Lazy.class == qualifier) {
252272
}
253273
}
254274
}
275+
255276
//关于BeanDefinitionCustomizer的理解,参看red.reksai.beandefinitioncustomizer.BeanDefinitionCustomizerTest
256277
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
257278
customizer.customize(abd);
258279
}
259280
//创建BeanDefinitionHolder,BeanDefinitionHolder其实就是对beanDefinition、beanName 和 aliases的封装,是为了后续传递方便而已,没有其他的用途
260281
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
282+
/**
283+
* ScopedProxyMode这个知识点比较复杂,需要结合web去理解,可以暂时放一下,等说到springMVC的时候再说【2019年11月19日16:01:12】
284+
* //todo
285+
*/
261286
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
262-
//注册bean定义
287+
/**
288+
* 把上述结构,即definitionHolder注册给registry
289+
* registry是{@link BeanDefinitionRegistry},这个类把BeanDefinition放在一个集合中,这个类就这个作用
290+
*/
263291
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
264292
}
265293

spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver
217217

218218
/**
219219
* Register one or more component classes to be processed.
220-
* 注册一个或多个要处理的组件类 ,例如:spring-learning中的${@link red.reksai.dao.UserDao}或者${@link red.reksai.config.AppConfig}
220+
* 注册一个或多个要处理的组件类 ,例如:spring-learning中的${@link red.reksai.dao.UserDao}或者${@link red.reksai.config.AppConfig},
221+
* 换句话说这个方法不仅可以注册配置类,也可以注册单个bean。
221222
* 在注册之后,必须调用{@link #refresh()} 才能完全解析上下文。
222223
* <p>Note that {@link #refresh()} must be called in order for the context
223224
* to fully process the new classes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package red.reksai.annotatedbeandefinitionreder;
2+
3+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
4+
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
5+
6+
/**
7+
* @author : <a href="mailto:[email protected]">gnehcgnaw</a>
8+
* @since : 2019/11/19 15:33
9+
*/
10+
public class AnnotatedBeanDefinitionReaderDemo {
11+
public static void main(String[] args) {
12+
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(new DefaultListableBeanFactory());
13+
}
14+
}

spring-learning/src/main/java/red/reksai/beandefinition/MultipleEXtends.java

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
/**
6+
* 接口的多继承demo
67
* @author : <a href="mailto:[email protected]">gnehcgnaw</a>
78
* @since : 2019/11/19 11:36
89
*/

0 commit comments

Comments
 (0)