前言:创建对象的协作关系称为装配,也就是DI(依赖注入)的本质。而在Spring容器中对bean的创建时就需要对它所依赖的对象进行注入装配。
- 在XML中进行显示配置;
- 在Java中进行显示配置;
- 隐式的bean发现机制和自动装配;
注:三种装配方式可以结合使用,但是推荐首选第3种自动装配,之后选用Java进行装配,最后选用XML进行装配。
自动装配优势:
- 便利,自动化装配,隐式配置代码量少。
自动装配限制:
- 基本数据类型的值、字符串字面量、类字面量无法使用自动装配来注入。
- 装配依赖中若是出现匹配到多个bean(出现歧义性),装配将会失败。
Spring实现自动装配两个步骤:
- 组件扫描(component scanning):Spring会扫描@Component注解的类,并会在应用上下文中为这个类创建一个bean。
- 自动装配(autowiring):Spring自动满足bean之间的依赖。
使用到的注解:
- @Component:表明这个类作为组件类,并告知Spring要为这个类创建bean。默认bean的id为第一个字母为小写类名,可以用value指定bean的id。
- @Configuration:代表这个类是配置类。
- @ComponentScan:启动组件扫描,默认会扫描所在包以及包下所有子包中带有@Component注解的类,并会在Spring容器中为其创建一个bean。可以用basePackages属性指定包。
- @RunWith(SpringJUnit4ClassRunner.class):以便在测试开始时,自动创建Spring应用上下文。
- @ContextConfiguration:告诉在哪加载配置。
- @Autowired:将一个类的依赖bean装配进来。
代码实现:
播放器接口:
public interface CDPlayer {// 播放器 void play(); }
唱片接口:
public interface CDDisk {// 唱片 void sing(); }
实现播放器接口的类:
import org.springframework.stereotype.Component; @Component public class MediaPlayer implements CDPlayer { private CDDisk cd;
@Autowired public MediaPlayer(CDDisk cd){ this.cd = cd; } @Override public void play() { cd.sing(); } }
实现唱片接口的类:
import org.springframework.stereotype.Component; @Component public class HuaHua implements CDDisk { private String title = "烟火里的尘埃"; private String singer = "华晨宇"; @Override public void sing() { System.out.println(title + "_" + singer); } }
Java配置类:
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan public class CDPlayerConfig { }
测试类:
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; // SpringJUnit4ClassRunner测试用,测试开始的时候自动创建Spring的应用上下文。 @RunWith(SpringJUnit4ClassRunner.class) // 测试用,去指定类加载配置 @ContextConfiguration(classes = CDPlayerConfig.class) public class CDTest { @Autowired private CDPlayer cdPlayer; @Test public void test() { cdPlayer.play(); } }
测试结果:
优点:
- 可以实现基本数据类型的值、字符串字面量、类字面量等注入。
使用到的注解:
- @Bean:默认情况下配置后bean的id和注解的方法名一样,可以通过name属性自定义id。
- @ImportResourse:将指定的XML配置加载进来
- @Import:将指定的Java配置加载进来。
- 注:不会用到@Component与@Autowired注解。
代码实现:
播放器接口与唱片接口:
public interface CDPlayer {// 播放器 void play(); } public interface CDDisk {// 唱片 void sing(); }
实现播放器的类:
public class MediaPlayer implements CDPlayer { private CDDisk cd;
@Autowired public MediaPlayer(CDDisk cd){ this.cd = cd; } @Override public void play() { cd.sing(); } }
实现唱片的类:
import java.util.List; public class HuaHua implements CDDisk { private String title; private String singer; private List<String> tracks; // 注入字面量 public HuaHua(String title, String singer, List<String> tracks) { this.title = title; this.singer = singer; this.tracks = tracks; } @Override public void sing() { System.out.println(title + "_" + singer); for (String track : tracks) { System.out.println(track); } } }
总配置类(将指定的配置类组合到一起):
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration // 将指定配置类组合到一起 @Import({CDPlayerConfig.class, CDDiskConfig.class}) public class SoundSystemConfig { }
播放器的配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CDPlayerConfig { private CDDisk cd; @Bean public CDPlayer cdPlayerConfig(CDDisk cd) { return new MediaPlayer(cd); } }
唱片配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; @Configuration public class CDDiskConfig { @Bean public CDDisk cdDisk() { return new HuaHua("专辑", "华晨宇", new ArrayList<String>() {{ add("烟火里的尘埃"); add("国王与乞丐"); add("齐天"); add("我的滑板鞋2016"); }}); } }
测试类:
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; // SpringJUnit4ClassRunner测试用,测试开始的时候自动创建Spring的应用上下文。 @RunWith(SpringJUnit4ClassRunner.class) // 测试用,去指定类加载配置 @ContextConfiguration(classes = SoundSystemConfig.class) public class CDTest { @Autowired private CDPlayer cd; @Test public void test() { cd.play(); } }
测试结果:
优点:什么都能做。
缺点:配置繁琐。
使用到的标签:
- <bean>:将类装配为bean,也可以导入java配置。属性id是为bean指定id,class是导入的类。
- <constructor-arg>:构造器中声明DI,属性value是注入值,ref是注入对象引用。
- spring的c-命名空间:起着和<constructor-arg>相似的作用。
- <property>:设置属性,name是方法中参数名字,ref是注入的对象。
- Spring的p-命名空间:起着和<property>相似的作用。
- <import>:导入其他的XML配置。属性resource是导入XML配置的名称。
代码实现(将Java配置改为了XML配置):
播放器接口与唱片接口:
public interface CDPlayer {// 播放器 void play(); } public interface CDDisk {// 唱片 void sing(); }
实现播放器的类:
public class MediaPlayer implements CDPlayer { private CDDisk cd; public MediaPlayer(CDDisk cd){ this.cd = cd; } @Override public void play() { cd.sing(); } }
实现唱片的类:
import java.util.List; public class HuaHua implements CDDisk { private String title; private String singer; private List<String> tracks; // 注入字面量 public HuaHua(String title, String singer, List<String> tracks) { this.title = title; this.singer = singer; this.tracks = tracks; } @Override public void sing() { System.out.println(title + "_" + singer); for (String track : tracks) { System.out.println(track); } } }
测试类:
import org.springframework.context.support.ClassPathXmlApplicationContext; public class CDTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("soundsystem.xml"); CDPlayer cd = context.getBean(CDPlayer.class); cd.play(); } }
总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.xsd"> <!--引入cdplayer-config.xml的配置--> <import resource="cdplayer-config.xml"/> </beans>
播放器的XML配置(将唱片的XML配置引入):
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c" 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"> <!--引入classpath:cd-config.xml的配置--> <import resource="classpath:cd-config.xml"/> <!--Spring的c命名空间写法,cd为构造器中参数--> <bean id="mediaPlayer" class="com.qsh.soundsystem.MediaPlayer" c:cd-ref="huahua"/> </beans>
唱片的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"> <!--使用<constructor-arg>元素--> <bean id="huahua" class="com.qsh.soundsystem.HuaHua"> <constructor-arg value="专辑"/> <constructor-arg value="华晨宇"/> <constructor-arg> <list> <value>烟火里的尘埃</value> <value>国王与乞丐</value> <value>齐天</value> <value>我的滑板鞋2016</value> </list> </constructor-arg> </bean> </beans>