今日から、春のソースコードについてブログを書く準備ができて、その後、ADO、アウトを開始しましょう!
1.環境の準備
1)図:
PersonServiceカテゴリ:
@Component
public class PersonService {
public void run(){
System.out.println("run方法执行了");
}
}
复制代码
SpringConfiguration类:
@ComponentScan("my.blog")
public class SpringConfiguration {
}
复制代码
TEST01カテゴリ:
public class Test01 {
public static void main(String[] args) {
//这个构造方法会把Spring所有的环境都准备好
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
PersonService person = ac.getBean(PersonService.class);
person.run();
}
}
复制代码
2.はじめに:ノートアプリケーション・コンテキストを設定します
AnnotationConfigApplicationContext
名前が示すように:注意事項は、私は、プレゼンテーションで使用されるアプリケーションコンテキストは、ノート方法です設定します
だから我々は必要なnew AnnotationConfigApplicationContext
このオブジェクトを。
それは、XML構成だが必要な場合はnew ClassPathXmlApplicationContext
、これは私が言うまでもなくなければならない、私はあなたが知っておくべきだと思います!
そして、オブジェクトのインスタンス化プロセスは、春には、人々は事は行って見ることができない最後に?そして、彼の謎を解明するために私に従ってください!
我々は上をクリックしnew AnnotationConfigApplicationContext
、彼はコンストラクタだものを見るために:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
//调用无参构造方法进行初始化一个读取器和扫描仪
this();
//这个方法的作用:主要是把配置类的信息加载进工厂中
//在这里需要你记住一个类:DefaultListableBeanFactory,后面会非常的重要
register(annotatedClasses);
//实例化所有被加了组件的对象
refresh();
}
复制代码
私たちは、コードが横断するの後ろに、この引数のコンストラクタは、実際には、1回限りの設定クラス以上のものを渡すことができます見つけるannotatedClasses
配列を
私たちは、見てthis()
行って何の事?
public AnnotationConfigApplicationContext() {
//这里也会先初始化父类的构造方法
//创建一个读取被加了注解的bean读取器 ,这个读取器到底什么鬼,不是这节的重点,可以先忽略
//你就知道他创建了一个读取器就完事了
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
复制代码
私たちは、に戻りregister(annotatedClasses);
、このセクションの兄であるこの方法は、我々は彼が春のために汚い仕事をやったことを見しようとしています!
3.負荷の設定クラス
我々は上をクリック register(annotatedClasses)
....ああ、それは無駄です!
クリックしてthis.reader.register(annotatedClasses);
メソッドを
私たちは、この方法が行き来し始めたときですannotatedClasses
配列を、私たちは、コンストラクタに渡されたワンタイム設定ファイル以上のものを書くことができます
トラバース開始しますannotatedClasses
(注:このプレゼンテーションを、私はちょうどコンフィギュレーションクラスを追加)、コールregisterBean(annotatedClass);
今回我々は上をクリック registerBean(annotatedClass);
クリックします doRegisterBean(annotatedClass, null, null, null);
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//(1)(解析:查看下面图)
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//这个不是重点,跳过
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//这个不是重点,跳过 instanceSupplier为null值
abd.setInstanceSupplier(instanceSupplier);
//(2)得到类的作用域 单例还是多例(解析:查看下面图)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//把类的作用域赋值给AnnotatedGenericBeanDefinition对象
abd.setScope(scopeMetadata.getScopeName());
//生成配置类的名称,如果@Component没有对应的名称 (我没有加名称)
//默认是类的小驼峰式命名称 (所有此时beanName为springConfiguration)
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/**
* (3)把AnnotatedGenericBeanDefinition对象传进
* 然后获取获取元数据metadata对象,判断元数据对象中是否存在lazy,DependsOn,Primary Role 等注解
* 如果有这些注解,则在AnnotatedGenericBeanDefinition对象中记录
*/
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));
}
}
}
//这个不是重点
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//(4)把abd放进去,赋值给了成员变量beanDefinition
//把BeanName赋值进去,可以说是增强版的abd对象
//查看后面的代码发现,其实definitionHolder就只是起到一个临时容器的作用
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//这个比较复杂,以后可以讲 和本节无关
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//(5)现在又把增强版的 definitionHolder 放到registry这个容器中
//BeanDefinitionRegistry 顾名思义 就是注册BeanDefinition的
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
复制代码
1)。私たちは、コードを見てAnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
、物事を行いますか?
デバッグを通じてアブド対象コンテンツを見ます
要約:
- 設定指定されたクラスによると、GenericBeanDefinitionオブジェクトを作成
- このGenericBeanDefinitionオブジェクトは、このような情報のメモとして、メタ情報のいくつかの種類が含まれています:スコープ、怠惰、ComponentScanおよびその他の注意事項を
- メタデータアノテーションはGenericBeanDefinition(メタ)オブジェクトに格納されています
- メタデータの注釈オブジェクトは、注釈のコレクションを持って、すべての注釈格納されている情報
2)次に見ます ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
あなたはこれを行う後にabd.setScope(scopeMetadata.getScopeName());
メソッドを
3)閲覧 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
に行くためにクリックしてください
金額は...、このメソッドは何もないように見えます...
ABDはオープンに渡すオブジェクト、およびオブジェクトABD abd.getMetadata()メタデータオブジェクトを通過しました
クリックします processCommonDefinitionAnnotations(abd, abd.getMetadata());
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
//判断当前的类是否加了lazy注解
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
//如果不为null,则把AnnotatedBeanDefinition中的 lazyInit 默认的false 修改为true
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"));
}
}
//判断元数据对象中时候有@Primary,默认时候primary是 false ,如果有则该为true
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
//判断时候有@DependsOn注解
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
//判断时候有@Role注解
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
//判断时候有@Description注解
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
复制代码
要約:
- オブジェクトはAnnotatedGenericBeanDefinitionに渡します
- メタデータmetdataオブジェクトの取得、メタデータオブジェクトは、怠惰、DEPENDSON、プライマリの役割他の注釈があるか否かを判断します
- これらのノートはAnnotatedGenericBeanDefinitionオブジェクト内に記録されている場合
4)を表示 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
デバッグました
5)を表示 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
に行くためにクリックしてください
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
//在这里又获取beanName的名称
String beanName = definitionHolder.getBeanName();
//现在把definitionHolder拆分了,又把abd对象拿出来了
//似乎definitionHolder就只是封装了一下,然后又给拆分, 可以理解为一个临时的容器
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
//这个不重要,spring当中处理别名的
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
复制代码
我々は上をクリック registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
、インタフェースでショートカットキーを押したままに見つかりCtrl + Alt + B
、3つの実装クラスがあり、フロントにご注意を促しDefaultListableBeanFactory
、ここでは、登場しました
選択 DefaultListableBeanFactory
@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");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//查看该bean时候在map集合中存储过
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("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.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("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);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
//---------------------------------------------------------------------------------------
//前面的代码都是一些判断,验证不是重点
//重点是这里的代码,前方高能
else {
//在这个方法中就把 beanDefinition 存储在 DefaultListableBeanFactory的map集合中
//顾名思义,beanDefinitionMap就是一个存储beanDefinition的map集合
//在这个集合当中还有Spring当中本身已经初始好的对象
this.beanDefinitionMap.put(beanName, beanDefinition);
//把beanName存储在这个list集合中
this.beanDefinitionNames.add(beanName);
//这个是去重的,不是重点
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
复制代码
this.beanDefinitionMap.put(beanName, beanDefinition);
前
this.beanDefinitionMap.put(beanName, beanDefinition);
後
this.beanDefinitionNames.add(beanName);
前
this.beanDefinitionNames.add(beanName);
後
完成したクラスの実装上の全体構成をロード、総括register(annotatedClasses);
行われているものの事?
- 構成メタデータカテゴリのロード
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
- アブドは、スコープを設定するオブジェクト
- メタデータ注釈を横断、注釈は、決められた時間に存在しています
- オブジェクト・クラスの構成情報が格納されている
DefaultListableBeanFactory
コレクションにbeanDefinitionMap - クラス名はコンフィギュレーションに保存されている
DefaultListableBeanFactory
コレクションのbeanDefinitionNames