Spring bean定义的优先级是什么? [英] What is the precedence of Spring beans definitions?

查看:121
本文介绍了Spring bean定义的优先级是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用相同的名称定义多个Spring bean时,哪一个会隐藏其他的?

When several Spring beans are defined with the same name, which one will hide the others?

假设我有几个用注释的类包org.example中的@Component(bean)以及包含以下内容的applicationContext.xml:

Let’s say I have several classes annotated with @Component("bean") in the package org.example, plus an applicationContext.xml that contains:

<context:component-scan base-package="org.example"/>
<alias name="aliasedBean" alias="bean"/>
<bean id="aliasedBean" class="org.example.AliasedBean"/>
<bean id="bean" class="org.example.XmlBean"/>
<import resource="otherApplicationContext.xml"/>

当我执行 applicationContext.getBean(bean时,将检索到哪个bean )

根据春天文档


每个bean都有一个或多个标识符。这些标识符在托管bean的容器中必须是唯一的。

Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean.

但是,我知道(因为我测试过)Spring不会这样做会抱怨。一个定义将隐藏其他定义。但我无法找出规则是什么。

However, I know (because I tested) that Spring won’t complain when this is done. One definition will hide the others. But I couldn’t find out what was the rule.

我想这样做是为了测试目的。我使用基于注释的配置来定义真实(生产)bean。然后我想使用特定于测试的XML配置文件来覆盖这些定义并注入模拟bean。

I want to do this for testing purpose. I use annotation based configuration in order to define real (production) beans. Then I want to use a test-specific XML configuration file to override these definitions and inject mock beans.

编辑:由于你有几个要求提供日志,我花了点钱时间创造一些。以下是:

Since you were several to ask for logs, I spent some time creating some. Here are they:

  0 INFO  org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3934f69a: startup date [Wed Mar 06 23:04:35 CET 2013]; root of context hierarchy
 45 INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
223 INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'bean': replacing [Generic bean: class [org.example.AnnotatedBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/etienne/Documents/Développement/Registre/workspace/SpringPrecedence/target/classes/org/example/AnnotatedBean.class]] with [Generic bean: class [org.example.XmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]]
223 INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [otherApplicationContext.xml]
246 INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'bean': replacing [Generic bean: class [org.example.XmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]] with [Generic bean: class [org.example.ImportedXmlBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [otherApplicationContext.xml]]
290 INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6aba4211: defining beans [bean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,aliasedBean,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
290 INFO  org.example.AliasedBean - Construction of AliasedBean.
302 INFO  org.example.Main - Application context loaded.
302 INFO  org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3934f69a: startup date [Wed Mar 06 23:04:35 CET 2013]; root of context hierarchy
302 INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6aba4211: defining beans [bean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,aliasedBean,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy

经过一些测试后,我发现在上下文创建期间我遇到异常,如果:

After some tests, I found out that I get an exception during context creation if:


  • 我有两个 @Component(bean)

  • 我在中有两个< bean id =bean/> 元素 XML文件。

  • I have two @Component("bean") or
  • I have two <bean id="bean"/> elements in the same XML file.

推荐答案


  • 豆类是以xml定义文件中的顺序注册。

    • Beans are registered in the order that are found in xml definition file.

      扫描的bean在找到xml标记的位置注册,但扫描的bean不能覆盖以前注册的bean定义。

      Scanned beans are registered at point that the xml tag is found but scanned beans cannot override previously registered bean definitions.

      如果 DefaultListableBeanFactory.allowBeanDefinitionOverriding 为true(默认情况下),Xml bean定义可以覆盖任何以前的bean定义。

      Xml beans definitions can override any previously bean definition if DefaultListableBeanFactory.allowBeanDefinitionOverriding is true (by default).

      所以XML胜利。

      如果你把组件扫描标签放在第一位,那么xml bean将会覆盖扫描的。如果你把它放在最后,扫描的bean将被忽略。

      If you put the component-scan tag first, xml beans will override scanned ones. If you put it last, scanned beans will be ignored.

      编辑

      别名在bean定义中的name属性中声明或使用别名标记声明时具有不同的行为。

      Aliases have diferent behavior if declared in name attribute in a bean definition or declared using the alias tag.


      • 使用别名标记声明的别名隐藏任何后面的bean定义具有相同的名称。

      • 在name属性中声明的别名通过抛出 BeanDefinitionParsingException 。

      • aliases declared with the alias tag hides any later bean definition with the same name.
      • aliases declared in name attribute prevent any other bean definition to use the same name by throwing a BeanDefinitionParsingException.

      例如:

       <bean id="foo" name="bar" class="Foo" />
       <bean id="bar" class="Bar" />   -- throw Exception (name bar is in use)
      

      <bean id="foo" class="Foo" />
      <alias name="foo" alias="bar" />
      <bean id="bar" class="Bar" /> -- Hidden by alias no exception thrown
      

      不同之处在于 BeanDefinitionParserDelegate 保存在bean元素嵌套的相同bean级别使用的名称和别名列表,并在解析bean定义时检查名称唯一性。

      The diference is that BeanDefinitionParserDelegate hold a list of names and aliases in use at the same bean level of beans element nesting and check for name uniqueness when parsing bean definitions.

      alias标记由 DefaultBeanDefinitionDocumentReader.processAliasRegistration()直接处理,解析器委托不知道这些名称。

      The alias tag is processed directly by DefaultBeanDefinitionDocumentReader.processAliasRegistration() and the parser delegate is unaware of this names.

      我不知道这是一个错误还是有意的但是 reference 没有说明任何内容,似乎预计别名的内部和外部声明具有相同的行为。

      I don't know if it's a bug or intentional but reference does not say anything about and seem to be expected that the internal and external declarations of aliases have the same behavior.

      这篇关于Spring bean定义的优先级是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆