我們現在仍以 xml 中配置 bean 的方式來 使用 Spring ,不考慮注解和掃包
配置相同id 的bean
定義一個 bean
類 TransactionManager
/*** @author maple 2018.09.10 下午10:27*/
public class TransactionManager {private static int counter = 0;private String beanName;public void setBeanName(String beanName) {this.beanName = beanName;}public TransactionManager() {System.out.println("===========> ===========> TransactionManager counter :" + (++counter));}public void hello() {System.out.println("===========> ===========> hello world, counter is " + counter + ", name is " + beanName);}
}
TransactionManager
有一個靜態變量 counter
可以判斷該類被實例化了幾次
Spring
管理 bean
<bean id="manager" class="com.hzways.multiply.TransactionManager"><property name="beanName" value="master"/>
</bean><bean id="manager" class="com.hzways.multiply.TransactionManager"><property name="beanName" value="master"/></bean>
照這種方式配置,spring 會直接報錯,在同一個xml文件下,這樣的配置是不允許的。
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'manager' is already used in this <beans> element
Offending resource: URL [file:/Users/maple/developer/spring-learning/maple-spring/maple-ioc/target/classes/services3.xml]
甚至 idea 都會進行提示
然而,我們有其他辦法讓Spring 能夠去接納 在 xml 中 配置 多個相同 的 bean 。
使用 import 的 方式 配置相同 id 的 bean
我們可以在 service.xml 中 配置 一個 bean ,并使用 import 的形式 導入另一個 spring 的xml 配置文件
service.xml
<bean id="manager" class="com.hzways.multiply.TransactionManager"><property name="beanName" value="master"/>
</bean><import resource="classpath*:services2.xml"/>
services2.xml
<bean id="manager" class="com.hzways.multiply.TransactionManager"><property name="beanName" value="slave"/>
</bean>
通過這樣的配置后,Spring不會報錯,啟動主程序。
public class Main {public static void main(String[] args) throws InterruptedException {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:services3.xml");applicationContext.start();TransactionManager helloWorld = applicationContext.getBean(TransactionManager.class);helloWorld.hello();Thread.sleep(Long.MAX_VALUE);}
}
控制臺打印如下:
===========> ===========> TransactionManager counter :1
===========> ===========> hello world, counter is 1, name is slave
分析控制臺日志發現,TransactionManager
類 只被加載了一次,而且加載的是從 service2.xml
里面定義的bean
。
我們調換順序,把 import 放在 bean 定義之上,再進行測試。
<import resource="classpath*:services3-bean.xml"/><bean id="manager" class="com.hzways.multiply.TransactionManager"><property name="beanName" value="master"/></bean>
這次程序果然打的是 master
===========> ===========> TransactionManager counter :1
===========> ===========> hello world, counter is 1, name is master
總結
spring不支持 直接在一個xml文件中定義兩個相同id的bean,但是可以通過 import 的形式 在另外一個xml文件中定義相同 id 的bean。
如果多個xml中定義相同 的 bean id ,Spring 默認會以最后加載到的bean為準,進行加載。