春の豆登録のソースコード分析

春の豆登録のソースコード分析

TSMYKJavaテクノロジープログラミング

序文

いわゆるBean登録は、後で使用するために、構成ファイルで構成された<bean>ノードをメモリーにロードすることです。

Beanの登録は、主に2つの段階に分けられます。1つは、構成ファイルを解析し、構成ファイルをメモリにロードして、ドキュメントの形式で保存する準備段階です。2つ目の段階は、ドキュメントを操作することです。その中のノードを取得します。、解析して登録します。

クラス図

慣例により、ソースコードを見る前に、Bean登録に関連するクラス図を見てみましょう。関係するクラスはたくさんあり、非常に複雑です。クラス図は次のとおりです。

春の豆登録のソースコード分析
最初に各クラスの主な実装を見て、最後に栗に基づいたBean登録の主なプロセスを見てください。

  1. AliasRegistry:エイリアスエイリアスへの単純な追加、削除、およびその他の操作を定義します。

  2. SimpleAliasRegistry:これはAliasRegistryインターフェースの実装クラスであり、mapを使用してエイリアスをマップします。

  3. BeanDefinitionRegistry:AliasRegistryインターフェースを継承し、BeanDefinitionへのさまざまな追加、削除、および変更を定義します。

  4. SingletonBeanRegistry:シングルトンBeanの登録と取得を定義します。

  5. DefaultSingletonBeanRegistry:SingletonBeanRegistryインターフェースの実装です。

  6. FactoryBeanRegistrySupport:DefaultSingletonBeanRegistryに基づいて、FactoryBeanの特別な処理関数が追加されました。

  7. BeanFactory:BeanおよびBeanのさまざまなプロパティへのアクセスを定義します。

  8. HierarchicalBeanFactory:BeanFactoryを継承し、親beanFactoryを拡張します。

  9. ConfigurableBeanFactory:ファクトリを構成するためのさまざまなメソッドを提供します。

  10. AbstractBeanFactory:FactoryBeanRegistrySupportとConfigurableBeanFactoryの機能を統合します。

  11. AutowireCapableBeanFactory:Beanの作成、自動注入、初期化、およびBeanの適用のためのポストプロセッサを提供します。

  12. AbstractAutowireCapableBeanFactory:AbstractBeanFactoryを合成し、インターフェースAutowireCapableBeanFactoryを実装します。

  13. ListableBeanFactory:さまざまな条件に従ってBean構成リストを取得します。

  14. ConfigurableListableBeanFactory:無視するタイプとインターフェースを指定するBeanFactoryの構成リスト。

  15. DefaultListableBeanFactory:主に登録後にBeanを処理するために、上記のすべての関数を統合します。

  16. XmlBeanFactory :DefaultListableBeanFactoryを拡張します。主に、カスタムリーダーXmlBeanDefinitionReaderを使用して、構成ファイルからBeanDefinitionを読み取ります。

BeanDefinition

BeanDefinitionはインターフェースであり、Springコンテナー内の構成ファイル<bean>タグの内部マニフェストです。<bean>タグの属性もBeanDefinitionの属性に対応します。これらは1対1で対応しています。 、つまり、<bean>タグはBeanDefinitionインスタンスに対応します。BeanDefinitionに関連するクラス図は次のとおりです。
春の豆登録のソースコード分析

実装クラスは3つあります。構成ファイルには親Beanと子Beanがあります。親BeanはRootBeanDefinitionで表され、子BeanはChildBeanDefinitionで表され、GenericBeanDefinitionは一般的なBeanDefinitionです。
春の豆登録のソースコード分析

AbstractBeanDefinition

AbstractBeanDefinitionはBeanDefinitionインターフェースを実装します。BeanDefinitionインターフェースでは、<bean>タグの対応する属性のsetter / getterメソッドのみが定義されますが、対応する属性は定義されません。対応する属性はAbstractBeanDefinitionクラスで定義され、Setterが書き換えられます。インターフェイスの/ getterメソッド:
春の豆登録のソースコード分析

AliasRegistry

AliasRegistryは、エイリアスエイリアスへの単純な追加、削除、およびその他の操作を定義します。
春の豆登録のソースコード分析

SimpleAliasRegistry

SimpleAliasRegistryは、AliasRegistryインターフェースの実装クラスであり、mapを使用してエイリアスをマップします。


public class SimpleAliasRegistry implements AliasRegistry {
    // 映射的 map
    private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
    // 注册别名
    @Override
    public void registerAlias(String name, String alias) {
        synchronized (this.aliasMap) {
            // 如果真实的名字和别名相同,则把别名移除点,因为真实的名字和别名相同没有意义
            if (alias.equals(name)) {
                this.aliasMap.remove(alias);
            }
            else {
                String registeredName = this.aliasMap.get(alias);
                // 如果已经注册过了
                if (registeredName != null) {
                    // 已经注册过了且别名没有发生变化,则不处理,没有必要再注册一次
                    if (registeredName.equals(name)) {
                        return;
                    }
                    // 如果别名不允许覆盖,则抛出异常
                    if (!allowAliasOverriding()) {
                        throw new IllegalStateException("");
                    }
                }
                checkForAliasCircle(name, alias);
                // 注册别名
                this.aliasMap.put(alias, name);
            }
        }
    }
   // 其他的方法都是通过 aliasMap 来判断的
}

BeanDefinitionRegistry

BeanDefinitionRegistryは、AliasRegistryインターフェースを継承し、BeanDefinitionへのさまざまな追加、削除、および変更を定義します。

春の豆登録のソースコード分析

SingletonBeanRegistry

SingletonBeanRegistryは、シングルトンBeanの登録と取得を定義します。
春の豆登録のソースコード分析

DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistryは、主にBeanを登録するためのSingletonBeanRegistryインターフェースの実装です。このクラスでは、登録のために多くのコレクションが定義されています


public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    // 如果bean为null则使用 NULL_OBJECT 来站位
    protected static final Object NULL_OBJECT = new Object();
    // 单例对象缓存,bean name --> bean instance
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object(256);
    // 单例对应的工厂缓存,可以使用工厂来创建单例对象 bean name --> ObjectFactory
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String,ObjectFactory<?>>(16);
    // 之前的单例对象
    private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
    // 已经注册过了的单例对象
    private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
    // 当前正在创建的单例对象集合
    private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

    // 需要排除的单例,什么意思呢?在创建单例的时候,如果该单例正在创建,就不会再创建了,就应该排除掉,如果某个单例在该集合中,则表示该单例正在创建
    private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
    // ..... 其他的集合 .....

   // 注册单实例的bean
    @Override
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        // 加锁:为什么用 ConcurrentHashMap 了还需要加锁?
        synchronized (this.singletonObjects) {
            // 判断是否已经注册过了,如果注册过了,则抛出异常
            Object oldObject = this.singletonObjects.get(beanName);
            if (oldObject != null) {
                throw new IllegalStateException("...");
            }
            // 注册
            addSingleton(beanName, singletonObject);
        }
    }
    // 真正的注册逻辑,就是把bean的名称和对象放到map中
    protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) { 
            // 注册,如果单例对象为null,则使用 NULL_OBJECT 站位
            this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
            // 该单例对象已经注册成功,则需要从工厂集合中移除,后面不需要再次注册
            this.singletonFactories.remove(beanName);
            // 之前注册过的对象也移除
            this.earlySingletonObjects.remove(beanName);
            // 向已经注册的单例集合中添加该实例
            this.registeredSingletons.add(beanName);
        }
    }

    // 根据 beanName 获取单例对象
    @Override
    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }
    // allowEarlyReference 参数是为了解决循环引用
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果该单例没有注册过,且正在注册
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                // 如果之前也没有注册过,且llowEarlyReference=true
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    // 获取该bean对应的工厂,通过工厂了创建还bean
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        // 创建成功后,需要去除
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        // 返回单例对象
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

    // 获取所有单例的name
    @Override
    public String[] getSingletonNames() {
        synchronized (this.singletonObjects) {
            return StringUtils.toStringArray(this.registeredSingletons);
        }
    }
    // 获取所有已经注册了的单例的个数
    @Override
    public int getSingletonCount() {
        synchronized (this.singletonObjects) {
            return this.registeredSingletons.size();
        }
    }

BeanFactory

BeanFactoryは、Springコンテナーにアクセスするためのルート・インターフェースであり、Beanを取得するためのさまざまなオーバーロードされたメソッドを定義します。
春の豆登録のソースコード分析

AbstractBeanFactory

AbstractBeanFactoryは、FactoryBeanRegistrySupportとConfigurableBeanFactoryの機能を組み合わせたBeanFactoryインターフェースの抽象実装クラスです。


public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    // bean的后置处理器 BeanPostProcessor 的集合
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
    // 当前正在创建的bean的名称集合
    private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<Object>("Prototype beans currently in creation");
    // 其他属性

    // 获取bean
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
    public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException{
        return doGetBean(name, requiredType, args, false);
    }
    // 获取bean,比较复杂,后面介绍了bean注册过,在来看
    protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {
      // 后面分析
    }
    // 其他方法
}

AbstractAutowireCapableBeanFactory

これはAbstractBeanFactoryを継承し、Beanの作成、属性の入力、自動アセンブリ、および初期化を提供するインターフェースAutowireCapableBeanFactoryを実装します。実行時にBean参照を処理し、マネージコレクションを解決し、初期化メソッドを呼び出すなど。また、コンストラクター、名前、タイプに応じて自動的に組み立てることができます。

このクラスは、後でBeanがロードされるときに分析されます。

DefaultListableBeanFactory

Beanを使用する前に、すべてのBeanが最初に登録され、登録されたBeanがマップの形式でクラスに配置されます。上記のクラス図から、このクラスは2つの異なるインターフェイスと抽象クラスを実装または継承していることがわかります。1つは登録に関連するインターフェイスと抽象クラスで、もう1つはBeanの取得に関連するインターフェイスです。 Bean登録に関連する部分:

それが定義する属性のいくつかを見てみましょう:


public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    // 序列化相关
    private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
            new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
    private String serializationId;

    // 当有相同名称不同实例时是否允许覆盖,默认允许
    private boolean allowBeanDefinitionOverriding = true;
    // 对于赖加载的bean,是否允许立即加载
    private boolean allowEagerClassLoading = true;

    // bean 注册的缓存,注册的bean就放在该集合中
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

    // 根据类型来返回所有bean的name,包含单例和原型两种模式的bean
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
    // 根据类型返回bean的name,只是返回单例的bean
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
    // 注册的bean的name的集合
    private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
    // 手动注册的单例的 bean name 集合
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
    // 在冻结配置的情况下缓存bean定义名称数组
     private volatile String[] frozenBeanDefinitionNames;
    // 是否可以为所有bean缓存bean 的元数据
    private volatile boolean configur

次に、Beanの登録に関連する方法を見てください。


@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){

    if (beanDefinition instanceof AbstractBeanDefinition) {
        // 注册前的最后一次检验,主要是对 AbstractBeanDefinition 的属性methodOverrides进行校验
        ((AbstractBeanDefinition) beanDefinition).validate();
    }
    BeanDefinition oldBeanDefinition;
    oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    // 如果已经注册该bean
    if (oldBeanDefinition != null) {
        // 如果已经注册过该bean,且设置为不允许覆盖,则抛出异常
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException();
        }
        // 如果允许覆盖,则直接注册,覆盖
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
        // 该bean还没注册,检查该工厂的bean创建阶段是否已经开始,即在此期间是否已将该bean标记为已创建。如果已经标记为创建
        if (hasBeanCreationStarted()) {
            // 无法再修改启动时集合元素(用于稳定迭代)
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                // 更新 beanDefinitionNames 这个集合
                List<String> updatedDefinitions = new 
 ArrayList<String(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                if (this.manualSingletonNames.contains(beanName)) {
                    // 安全的从 manualSingletonNames 集合中移除该bean
                    Set<String> updatedSingletons = new LinkedHashSet<String(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        }
        else {
            // 如果仍然在启动注册阶段,则直接注册
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }
}

// 注册单例的bean
@Override
public void registerSingleton(String beanName, Object singletonObject) {
    // 调用父类 DefaultSingletonBeanRegistry 的方法进行注册,上面已经分析过
    super.registerSingleton(beanName, singletonObject);
    // 同样的,如果该bean已经标注为开始创建, 
    if (hasBeanCreationStarted()) {
        synchronized (this.beanDefinitionMap) {
            if (!this.beanDefinitionMap.containsKey(beanName)) {
                // 安全的更新 manualSingletonNames 
                Set<String> updatedSingletons = new LinkedHashSet<String(this.manualSingletonNames.size() + 1);
                updatedSingletons.addAll(this.manualSingletonNames);
                updatedSingletons.add(beanName);
                this.manualSingletonNames = updatedSingletons;
            }
        }
    }
    else {
        //直接注册
        if (!this.beanDefinitionMap.containsKey(beanName)) {
            this.manualSingletonNames.add(beanName);
        }
    }
}

くるみ

栗を通して上記のクラスを見て、豆の登録プロセスに精通しましょう

まず、Bean構成のすべてのプロパティを確認します。


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd"   >

    <bean id="testBean" class="main.tsmyk.pojo.MyTestBean"
          abstract="true" autowire="byName" autowire-candidate="true"
          depends-on="conversionService" destroy-method="getName"
          factory-bean="environment" factory-method=""
          init-method="getName" lazy-init="true" name="myTestBean"
          parent="environment" primary="true" scope="singleton" >
        <property name="name" value=""/>
        <constructor-arg name="a" value="a" type="TestBean" index="" ref="">
            <bean name="" />
            <map key-type="" value-type=""/>
        </constructor-arg>
        <qualifier value="a" type=""/>
        <lookup-method />
        <meta key="" value=""/>
        <replaced-method/>
    </bean>

    <alias name="testBean" alias="aaa"/>
    <import resource=""/>
</beans>

テストコード:


 public static void main(String[] args){
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("myspring.xml"));
        MyTestBean testBean = (MyTestBean) beanFactory.getBean("testBean");
        System.out.println(testBean.getName());
    }

最初の部分

前述のように、Beanの登録は主に2つの部分に分けられます。最初の部分は構成ファイルをメモリ形式のドキュメントにロードし、2番目の部分はドキュメントのノードを解析して登録します。この部分はあまり紹介ではありません。ドキュメントを形成するために構成ファイルがメモリにロードされていることを知っておく必要があるだけです。
構成ファイルの解析のシーケンス図は次のとおりです。
春の豆登録のソースコード分析

最後に、Beanを登録するロジックは、DefaultBeanDefinitionDocumentReaderクラスのparseBeanDefinitions()メソッドから始まります。これは次のとおりです。


    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        // 表示的是默认的节点
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                        // 解析默认的节点
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        // 解析自定义节点
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            // 解析自定义节点
            delegate.parseCustomElement(root);
        }
    }

Spring構成ファイルには、Bean宣言の2つのタイプがあります。1つは<bean>などのデフォルト宣言であり、もう1つは<tx:annotation-driver>などのカスタム宣言であるため、メソッドは2つのセットに分割されます。分析ロジックの。

デフォルトタグの解決

デフォルトラベルの解析は、parseDefaultElement()メソッドに対応します


private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析 <import>
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // 解析 <alias>
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    // 解析 <bean>
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    // 解析 <beans>
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        doRegisterBeanDefinitions(ele);
    }
}

<bean>タグの分析と登録


protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析 bean的各种属性
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        // 如果该bean包含自定义的子标签,则对自定义子标签解析
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        // 注册
        BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        // 发消息,可以忽略
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

Beanのプロパティと子ノードを分析します


public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return parseBeanDefinitionElement(ele, null);
}
//containingBean: 父 bean
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // id 属性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    // name 属性
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    // name 属性值就是别名 alias,解析 name 的值,放到 alias 集合中,
    List<String> aliases = new ArrayList<String>();
    if (StringUtils.hasLength(nameAttr)) {
        // 这里可以看到 name 的值可以使用 , ; 和空格进行分割
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
        aliases.addAll(Arrays.asList(nameArr));
    }
    // beanName 的值就是 id 的值
    String beanName = id;
    // 如果 beanName 为空,且 alias 不为空,则获取第一个别名作为beanName
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
        beanName = aliases.remove(0);
    }
    // 如果父 bean 为空,则检查beanName的唯一性
    if (containingBean == null) {
        checkNameUniqueness(beanName, aliases, ele);
    }
    // 创建 AbstractBeanDefinition 在该方法内部,会解析bean所有的属性和子节点
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            // 如果 beanName为空,则根据spring中的命名规则为该bean生成对应的beanName
            if (containingBean != null) {
                beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
            }
            else {
                beanName = this.readerContext.generateBeanName(beanDefinition);
                // 把该bean的类名也注册为别名,为了向后兼容
                String beanClassName = beanDefinition.getBeanClassName();
                if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                    aliases.add(beanClassName);
                }
            }
        }
        // BeanDefinitionHolder 创建对象返回,分别设置对应的属性值
        String[] aliasesArray = StringUtils.toStringArray(aliases);
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }
    return null;
}

// 解析属性和子节点
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
    // 不知道干嘛用
    this.parseState.push(new BeanEntry(beanName));

    // 获取 class 属性的值
    String className = null;
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }
    // 获取 parent 属性的值
    String parent = null;
    if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
        parent = ele.getAttribute(PARENT_ATTRIBUTE);
    } 
    // 创建 AbstractBeanDefinition 对象,底层是 GenericBeanDefinition
    AbstractBeanDefinition bd = createBeanDefinition(className, parent);
    // 解析所有属性
    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
    bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    // 解析 <meta>
    parseMetaElements(ele, bd);
    // 解析 <lookup-method />
    parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
    // 解析 <replaced-method/>
    parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
    // 解析 <constructor-arg />
    parseConstructorArgElements(ele, bd);
    // 解析 <property />
    parsePropertyElements(ele, bd);
    // 解析 <qualifier />
    parseQualifierElements(ele, bd);

    bd.setResource(this.readerContext.getResource());
    bd.setSource(extractSource(ele));

    return bd;
}

// 解析所有属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
        BeanDefinition containingBean, AbstractBeanDefinition bd) {
    // singleton 和 scope 只能有一个
    if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
        error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
    }
    else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
    }
    else if (containingBean != null) {
        bd.setScope(containingBean.getScope());
    }
    // abstract 属性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }
    // lazyInit 属性
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
        lazyInit = this.defaults.getLazyInit();
    }
    bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
    // 其他属性
}

// 解析 <meta>
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
    NodeList nl = ele.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        // 判断是 meta 节点
        if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
            Element metaElement = (Element) node;
            String key = metaElement.getAttribute(KEY_ATTRIBUTE);
            String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
            BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
            attribute.setSource(extractSource(metaElement));
            attributeAccessor.addMetadataAttribute(attribute);
        }
    }
}
// 其他节点的解析类似

Beanのすべての属性と子ノードを解析した後、Beanによって定義されたすべての情報を含むBeanDefinitionHolderオブジェクトを取得し、オブジェクトをパッケージ化します。なぜパッケージ化する必要があるのですか?構成されたBeanに子ノードがあり、子ノードがユーザー定義ノードである場合、子ノードはパッケージ化されます。


bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
    return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
}
// 包装,containingBd:父bean
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {
    // 最终的 BeanDefinitionHolder 
    BeanDefinitionHolder finalDefinition = definitionHolder;

    // 遍历所有属性,看看否是有适用于修改的属性
    NamedNodeMap attributes = ele.getAttributes();
    for (int i = 0; i < attributes.getLength(); i++) {
        Node node = attributes.item(i);
        finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
    }
    // 遍历所有子节点,看看是否有适用于修改的子节点
    NodeList children = ele.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        Node node = children.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
        }
    }
    return finalDefinition;
}

public BeanDefinitionHolder decorateIfRequired(
        Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
    // 获取自定义的命名空间
    String namespaceUri = getNamespaceURI(node);
    // 不是默认的命名空间,则是自定义的命名空间
    if (!isDefaultNamespace(namespaceUri)) {
        // 根据命名空间获取对应的处理器
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler != null) {
            return handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
        }
    }
    return originalDef;
}

Beanの定義が解析されたので、次のステップは、解析されたBeanをSpringコンテナーに登録することです。


BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

// 注册
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {

    // bean的名字
    String beanName = definitionHolder.getBeanName();
    // 使用 DefaultListableBeanFactory 来注册bean,即把beanName和对应的BeanDefinition 注册到map中,上面分析DefaultListableBeanFactory 类时已经分析过该方法了
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 注册别名,调用 SimpleAliasRegistry 的 registerAlias 来注册别名,上面已经分析该类了
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

この時点で、<bean>タグの登録は分析されており、<import>、<alias>、および<beans>タグの分析はまだあります。<alias>タグの登録については、分析しました。上記の分析のSimpleAliasRegistry、および残りの2つは同じルーチンです。

この時点で、Bean登録の分析は完了です。

おすすめ

転載: blog.51cto.com/15077536/2608547