我有一个关于组件扫描的问题,以及在 Spring Version 3.0.5.RELEASE 中对同一服务类的XML配置中使用额外的bean定义。
我创建了一个用
注释的“MyService”类@Service( "myService" )
并且对于同一个类有一个bean定义,如下所示:
<bean id="myService" class="....MyService" />
我放了一个
System.out.println( "MyService has been instantiated" );
消息进入MyService类的构造函数。当我的应用程序启动时,该消息将仅显示在控制台一次。 Spring似乎很聪明,可以检测到只有一个具有id“myService”的类的实例。
但即使我将注释更改为
@Service( "myService2" )
并将xml bean定义id保留为“myService”,该类只会实例化一次。
我的两个问题是:
虽然这是我目前想要的行为,但是可能将XML bean定义和组件扫描混合在一个类中,让它使用不同的Bean ID实例化两次吗? / p>
有谁知道,Spring的“幕后”机制是什么? Spring如何决定何时只实例化一次类? (也许不允许将组件扫描和XML bean定义混合在同一个类中?)
非常感谢你的帮助!
答案 0 :(得分:6)
您的问题2.可以轻松回答。 Spring根据其范围实例化bean。无论您使用xml还是基于注释的配置,默认范围都是“singleton”。如果将bean声明为scope = prototype,则每次向容器请求bean时都会实例化它。
作为注释:
@Scope(StandardScopes.PROTOTYPE)
在xml中:
<bean .... scope="prototype">
如果你需要正好两个 bean的实例,最好的方法是用XML认为其中有两个用dfiferent名称。
关于你的问题1,我不知道是否可以声明一个类的两个实例,一个使用注释,一个使用XML。您确定类路径扫描在您的示例中确实有效吗?省略XML bean声明并再试一次,那么你有一个bean的实例吗?如果没有,您应该首先修复类路径扫描,因为它似乎不起作用。
无论如何,最重要的问题是:你为什么要这样做?混合两种类型的配置将创建一些不可维护的代码。不要混淆配置类型,只选择一个,或告诉我们为什么你需要它。
答案 1 :(得分:1)
您可以使用组件扫描,同时在xml中定义bean。然而,这也取决于bean范围。
阅读此post以获取更多信息。
如果启用了组件扫描,spring将尝试创建一个bean,即使已经在spring config xml中定义了该类的bean。但是,如果spring配置文件中定义的bean和自动发现的bean具有相同的名称,则spring在进行组件扫描时不会创建新的bean。如果bean没有no-args构造函数,则至少有一个构造函数必须自动连接。如果没有构造函数是自动连接的,spring将尝试使用默认的no-args构造函数创建一个对象。