Bean 装配
spring容器装配Bean
没咖啡豆的咖啡机用处不大,同样没有装配bean的容器不能发挥任何功能。
何为bean装配
创建bean的交互行为
bean装配的方式
这边仅做简单演示
显式XML方式
如下在xml中声明了bean定义及bean之间的依赖:bean player依赖bean cd
id为bean的名称,如果bean要被其他的bean依赖,则需要显式给定id
class为bean的完全限定的类型
constructor-arg元素定义构造函数要注入的字面值或bean依赖,这边ref表示依赖另一bean
也可以使用c:名称空间(不能用于集合)具体可参考Spring Framework文档
<?xml version="1.0" encoding="UTF-8"?>
<!--bean定义根元素-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cd" class="soundsystem.SgtPeppers"></bean>
<bean id="player" class="soundsystem.CDPlayer">
<constructor-arg ref="cd"/>
</bean>
</beans>
验证
public class XMLMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new
ClassPathXmlApplicationContext(
"/META-INF/spring/soundsystem.xml");
MediaPlayer cdPlayer = ctx.getBean(MediaPlayer.class);
//输出soundsystem.CDPlayer@
System.out.println(cdPlayer.toString());
}
}
显式Java配置方式
如下在bean方法中调用了sgtPeppers()方法,勿以为返回了新的SgtPeppers实例。
Spring Bean默认是单实例的,Spring拦截对sgtPeppers()方法的调用,返回已创建的实例。
@Configuration
public class CDPlayerConfig {
@Bean
public SgtPeppers sgtPeppers() {
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer() {
return new CDPlayer(sgtPeppers());
}
// //也可以这样注入cd依赖
// @Bean
// public CDPlayer cdPlayer(CompactDisc cd) {
// return new CDPlayer(cd);
// }
}
单元测试方式验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerJavaTest extends AbstractJUnit4SpringContextTests {
@Test
public void cdPlayerShouldNotBeNull() {
MediaPlayer cd = applicationContext.getBean(CDPlayer.class);
assertNotNull(cd);
}
}
隐式bean发现和自动装配
使用@Component注解声明bean
使用@Autowired注解声明bean的自动装配
@Component
public class SgtPeppers implements CompactDisc {
public void play() {
}
}
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
@ComponentScan
@Configuration
public class CDPlayerConfig {
}
验证自动装配
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerAutowiredTest {
@Autowired
private MediaPlayer player;
@Test
public void cdPlayerShouldNotBeNull() {
assertNotNull(player);
}
}
XML配置、Java配置的混合使用
以Java配置为主,XML配置为辅
<bean id="cd" class="soundsystem.SgtPeppers"></bean>
public class SgtPeppers implements CompactDisc {
}
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
}
@ComponentScan
@Configuration
@ImportResource("classpath:META-INF/spring/soundsystem.xml")
public class CDPlayerConfig {
}
验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class MixedWireTest extends AbstractJUnit4SpringContextTests {
@Test
public void cdPlayerShouldNotBeNull() {
MediaPlayer cd = applicationContext.getBean(CDPlayer.class);
assertNotNull(cd);
}
}
以XML配置为主,Java配置为辅
<bean id="cd" class="soundsystem.SgtPeppers"></bean>
<!--将java config配置为bean-->
<bean class="soundsystem.CDPlayerConfig"></bean>
@ComponentScan
@Configuration
public class CDPlayerConfig {
}
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
}
public class SgtPeppers implements CompactDisc {
}
验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/META-INF/spring/soundsystem.xml")
public class MixedWireXMLCenterTest extends AbstractJUnit4SpringContextTests {
@Test
public void cdPlayerShouldNotBeNull() {
MediaPlayer cd = applicationContext.getBean(CDPlayer.class);
assertNotNull(cd);
}
}
使用根配置支持配置的模块化及混合配置
基于Java配置的根配置
//CdConfigure模块配置
package soundsystem.cd;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan(basePackageClasses = soundsystem.SgtPeppers.class)
@Configuration
public class CdConfigure {
}
//CDPlayerConfig模块配置
package soundsystem.player;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan(basePackageClasses = soundsystem.CDPlayer.class)
@Configuration
public class CDPlayerConfig {
}
//根配置
@Configuration
@Import({CDPlayerConfig.class, CdConfigure.class})
public class CDAndPlayerConfig {
}
//bean CDPlayer
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
}
//bean SgtPeppers
@Component
public class SgtPeppers implements CompactDisc {
}
验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= CDAndPlayerConfig.class)
public class JavaRootConfigTest extends AbstractJUnit4SpringContextTests {
@Test
public void cdPlayerShouldNotBeNull() {
MediaPlayer cd = applicationContext.getBean(CDPlayer.class);
assertNotNull(cd);
}
}
基于XML配置的根配置
<!--cdconfig.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<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="cd" class="soundsystem.SgtPeppers"></bean>
</beans>
<!--cdplayer.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<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">
<import resource="cdconfig.xml"/>
<bean id="player" class="soundsystem.CDPlayer">
<constructor-arg ref="cd"/>
</bean>
</beans>
<!--soundsystem.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="cdconfig.xml"/>
<import resource="cdplayer.xml"/>
</beans>
验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/META-INF/spring/soundsystem.xml")
public class XMLRootConfigTest extends AbstractJUnit4SpringContextTests {
@Test
public void cdPlayerShouldNotBeNull() {
MediaPlayer cd = applicationContext.getBean(CDPlayer.class);
assertNotNull(cd);
}
}
混合配置的根配置思想和上面一样,就不做过多描述
装配方式的选择
这么多装配方式究竟选哪一种?我想更多人愿意选自动装配,这没有错。总体优先选择自动装配和Java配置。
但具体情况具体分析,在使用遗留系统或第三方源码不可得的组件等情况下可能需要使用XML配置或者混合配置。
ps:我的个人博客 强哥