Spring具有非常大的灵活性,它提供了三种主要的装配机制:
- 在XML中进行显式配置。
- 在Java中进行显式配置。
- 隐式的bean发现机制和自动装配。
一、自动化装配bean
Spring从两个角度来实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
- 自动装配(autowiring):Spring自动满足bean之间的依赖。
1.首先创建CompactDisc.java文件,里面顶一个一个接口:
package com.df.test.service.impl;
public interface CompactDisc {
void play();
}
2.然后定义它的实现类:
package com.df.test.service.impl;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc {
public void play() {
// TODO Auto-generated method stub
System.out.println("播放音乐...");
}
}
需要注意的就是SgtPeppers类上使用了@Component注解。这个简单的注解表明该类会作为组件类,并告知Spring要为这个类创建bean。没有必要显式配置SgtPeppersbean,因为这个类使用了@Component注解,所以Spring会为你把事情处理妥当。不过,组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。如下设置Spring对组件进行扫描:
package com.df.test.service.impl;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
使用了@ComponentScan注解,这个注解能够在Spring中启用组件扫描。如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包。因为CDPlayerConfig类位于com.df.test.service.impl包中,因此Spring将会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类。并且会在Spring中自动为其创建一个bean。
当然也可以XML来启用组件扫描:
<context:component-scan base-package="com.df.test.service.impl" />
测试代码如下:
package com.df.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.df.test.service.impl.CDPlayerConfig;
import com.df.test.service.impl.CompactDisc;
import com.df.test.service.impl.SgtPeppers;
@RunWith(SpringJUnit4ClassRunner.class) //表示继承了SpringJUnit4ClassRunner类
@ContextConfiguration(classes= CDPlayerConfig.class)
public class JavaTestMethod {
@Autowired CompactDisc cd;//这里,不论我是用CompactDisc接口还是SgtPeppers实现类,下面都有输出,都是同一个对象SgtPeppers。
@Test
public void testMethod() {
cd.play();
}
}
@Component基本使用。
Spring应用上下文中所有的bean都会给定一个ID。在前面的例子中,尽管我们没有明确地为SgtPeppersbean设置ID,但Spring会根据类名为其指定一个ID。具体来讲,这个bean所给定的ID为sgtPeppers,也就是将类名的第一个字母变为小写。我们也可以给bean命名,像下面代码这样。有时候可以用@Named代替@Component使用:
@Component("myComponentName")
public class SgtPeppers implements CompactDisc {
...
}
@ComponentScan基本使用。
不但可以默认设置,还可以指定多个不同的基础包作为扫描对象,使用basePackages属性,String[]类型。
另外一种方法,那就是将其指定为包中所包含的类或接口,使用 basePackageClasses属性,这些类所在的包将会作为组件扫描的基础包。,Class<?>[]类型:。
//一下两种方法,任意一种都可以实现
@Configuration
@ComponentScan(basePackages = {"com.df.test.service.impl","com.df.test.dao"})
public class CDPlayerConfig {
}
@Configuration
@ComponentScan(basePackageClasses = {SgtPeppers.class})
public class CDPlayerConfig {
}
@Autowired 实现自动装配。
简单来说,自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。假如有且只有一个bean匹配依赖需求的话,那么这个bean将会被装配进来。如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。因为是按照类型进行匹配,所以如果有多个bean都能满足依赖关系的话,Spring将会抛出一个异常,表明没有明确指定要选择哪个bean进行自动装配。@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上,还可以在属性上。如下代码,下面三个属性对象,都会完成自动装配,可以用@Inject在大多数情况下来代替@Autowired 。@Named和@Inject来源于Java依赖注入规范。
package com.df.test.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
@Autowired
private CompactDisc cd;
private CompactDisc cd2;
private CompactDisc cd3;
@Autowired
public CDPlayer(CompactDisc cd2) {
this.cd2 = cd2;
}
@Autowired
public void setCd3(CompactDisc cd3) {
this.cd3 = cd3;
}
public void play(){
cd.play();
cd2.play();
cd3.play();
}
}
二、通过Java代码装配bean
通过JavaConfig显式配置Spring:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayer02 {
@Bean
public CompactDisc getBeanI(){
return new SgtPeppers();
}
}
@Bean注解基本使用。
创建JavaConfig类的关键在于为其添加@Configuration注解,@Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。所以这里就很灵活了,可以一个方法,返回很多个不同的对象根据不同的逻辑条件。默认情况下,bean的ID与带有@Bean注解的方法名是一样的。也可以通过name属性指定一个不同的名字。
三、通过XML装配bean
Spring刚出来的时候,就是以这种方式。所以这里就不做过多解释了。可以通过set方法注入,也可以通过构造方法注入。
<?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-2.5.xsd">
<bean id="customerDAO" class="com.sanxin.org.jdbc.JdbcCustomerDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
我是分割线
混合配置
以上已经将三种装配bean的 方式讲完了,现在说说混合配置
1.JavaConfig配置之间相互引用
假设由于有两个JavaConfig配置的类:
@Configuration
public class CDPlayer02 {
@Bean
public CompactDisc getBean02(){
return new SgtPeppers02();
}
}
@Configuration
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
我们需要有一种方式将这两个类组合在一起,可以这样做,使用@Import:
@Configuration
@Import(CDPlayer02 .class)
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
也可以干脆这样:
@Configuration
@Import({CDPlayer01 .class,CDPlayer2 .class})
public class CDPlayer01 {
}
2.在JavaConfig中引用XML配置
假设有cd-config.xml配置文件
@Configuration
@Import(CDPlayer02 .class)
@ImportResource("classpath:cd-config.xml")
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
3.在XML配置中引用JavaConfig
<?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-2.5.xsd">
<!-- 这就是那个JavaConfig配置类 -->
<bean class = "com.df.test.service.impl.CDConfig"/>
<bean id="customerDAO" class="com.sanxin.org.jdbc.JdbcCustomerDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
4.在XML配置中引用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-2.5.xsd">
<!-- 这就是那个JavaConfig配置类 -->
<bean class = "com.df.test.service.impl.CDConfig"/>
<!-- 这就是另一个那个xml配置文件 -->
<improt resource = "cdplayer-config.xml" />
</beans>
以上就是bean装配的三种方式。上一篇Spring容器。