一.Spring装配机制
  Spring提供了三种主要的装配机制:
    1.在XML中进行显示配置
    2.在Java中进行显示配置
    3.隐式的bean发现机制和自动装配
--自动化装配bean
  Spring可以通过注解来进行自动装配(无需再手动写配置文件),Spring从两个角度实现自动化装配:
    1.组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean;
    2.自动装配(autowiring):Spring自动满足bean之间的依赖;
--以CD及CD播放器为示例,如果我们不将CD注入到CD播放器之中,那么CD播放器其实是没有太大用处的,在CompactDisc接口中定义CD的概念:

 package cd;

 /**
* @author : S K Y
* @version :0.0.1
*/
public interface CompactDisc {
/**
* 播放CD
*/
void play();
}

--定义实现类

 package cd;

 import org.springframework.stereotype.Component;

 /**
* @author : S K Y
* @version :0.0.1
*/
@Component //使用@Component注解将告知Spring为这个类创建bean
public class SgtPeppers implements CompactDisc {
@Override
public void play() {
System.out.println("SgtPeppers播放中....");
}
}

--想要实现自动装配,单单使用@Component是不够的,我们还需要启动组件扫描来完成配置,在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"
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">
<context:component-scan base-package="cd"/> <!--组件扫描,扫描cd包-->
</beans>

--使用Junit测试来验证CompactDisc是否真的被创建成功,使用Java配置来完成:

 package cd;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration
@ComponentScan(basePackages = {"cd"})
public class CDPlayerConfig {
}
 package cd.test;

 import cd.CDPlayerConfig;
import cd.CompactDisc;
import org.junit.Assert;
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; /**
* @author : S K Y
* @version :0.0.1
*/
@RunWith(SpringJUnit4ClassRunner.class) //需要使用spring-test-4.3.4.RELEASE.jar
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Autowired
private CompactDisc cd; @Test
public void cdShouldNotBeNull(){
Assert.assertNotNull(cd);
}
}

--事实上Spring应用上下文中所有的bean都会给定一个ID,在上述的例子中,我们使用@Autowired注解的时候并没有设置其ID值,此时Spring会根据类名为其分配一个ID值(ID值就是类名,并且首字母小写)。当然我们也可以在使用@AutoWired的时候为其自定义ID值:

 package cd;

 import org.springframework.stereotype.Component;

 /**
* @author : S K Y
* @version :0.0.1
*/
@Component("myPeppers") //使用@Component注解将告知Spring为这个类创建bean
public class SgtPeppers implements CompactDisc {
@Override
public void play() {
System.out.println("SgtPeppers播放中....");
}
}
     @Test
public void getBeanByID(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CDPlayerConfig.class);
CompactDisc myPeppers = context.getBean("myPeppers", CompactDisc.class);
myPeppers.play();
}

--运行结果

九月 07, 2019 10:35:36 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
九月 07, 2019 10:35:36 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
九月 07, 2019 10:35:36 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
九月 07, 2019 10:35:36 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
九月 07, 2019 10:35:36 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
信息: Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@6bdf28bb, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@6b71769e, org.springframework.test.context.support.DirtiesContextTestExecutionListener@2752f6e2]
九月 07, 2019 10:35:36 上午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@3a03464: startup date [Sat Sep 07 10:35:36 CST 2019]; root of context hierarchy
九月 07, 2019 10:35:37 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@635eaaf1: startup date [Sat Sep 07 10:35:37 CST 2019]; root of context hierarchy
SgtPeppers播放中....
九月 07, 2019 10:35:37 上午 org.springframework.context.support.GenericApplicationContext doClose
信息: Closing org.springframework.context.support.GenericApplicationContext@3a03464: startup date [Sat Sep 07 10:35:36 CST 2019]; root of context hierarchy Process finished with exit code 0

--同时Spring支持将@Named作为@Component注解的替代方法,但是更多的是使用@Component注解来完成

二.设置组件扫描的基础包
  在上述示例中,对CDPlayerConfig类使用了@ComponentScan注解.并使用basePackages={"cd"}来指定了所需要扫描的包,观察@ComponentScan注解的实现:

@AliasFor("basePackages")
String[] value() default {};

@AliasFor("value")
String[] basePackages() default {};

--可以发现为basePackages设置了default属性,虽然在定义的类中没有给出具体的值,但是在Spring的内部实现中,会将配置类所在的包作为基础包来进行组件扫描,同时可以发现所定义的basePackages为一个数组,因此我们可以指定多个包为所需要扫描的包;当然还有另一种方法,我们可以指定包中所含有的类或接口:Class<?>[] basePackageClasses() default {}:

 package cd;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration
@ComponentScan(basePackageClasses = {CompactDisc.class})
public class CDPlayerConfig {
}
     @Test
public void bothShouldNotBeNull(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CDPlayerConfig.class);
CompactDisc myPeppers = context.getBean("myPeppers", CompactDisc.class);
CompactDisc cdPlayer = context.getBean("cdPlayer", CompactDisc.class);
myPeppers.play();
cdPlayer.play();
}

--运行结果

SgtPeppers播放中....
CDPlayer播放....
九月 07, 2019 10:58:38 上午 org.springframework.context.support.GenericApplicationContext doClose
信息: Closing org.springframework.context.support.GenericApplicationContext@3a03464: startup date [Sat Sep 07 10:58:37 CST 2019]; root of context hierarchy Process finished with exit code 0

--我们可以发现实现自CompactDisc接口的所有类都成功的被自动扫描加入了Spring容器之中,因此我们可以优化我们的代码结构,我们可以用一个空接口,所有需要进行自动扫描的组件都可以使用这个空接口来进行标记(在Java序列化之中Serializable 接口就是一个空接口,只是用来声明某个类具有可以序列化的功能),这样一来对于项目代码的维护和重构将更加的友好.
--在你的应用程序中,如果所有的对象都是独立的,彼此之间没有任何 依赖,就像SgtPeppersbean这样,那么你所需要的可能就是组件扫 描而已。但是,很多对象会依赖其他的对象才能完成任务。这样的 话,我们就需要有一种方法能够将组件扫描得到的bean和它们的依赖 装配在一起。要完成这项任务,我们需要了解一下Spring自动化配置 的另外一方面内容,那就是自动装配。

三.通过为bean添加注解实现自动装配
  自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,Spring会在应用中寻找匹配某个bean需求的其他bean.为了声明要进行自动装配可以借助@AutoWired注解来完成:

 package cd;

 import knights.Knight;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration
@ComponentScan(basePackageClasses = {CompactDisc.class,CDorDVDPlayer.class})
public class CDPlayerConfig {
}
 package cd;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
* @author : S K Y
* @version :0.0.1
*/
@Component("CDorDVDPlayer")
public class CDorDVDPlayer {
private CompactDisc compactDisc; @Autowired //@AutoWired注解可以使用在构造器上,这样bean ID为myPeppers的bean将会为这个构造器自动装配进去
public CDorDVDPlayer(CompactDisc myPeppers) {
this.compactDisc = myPeppers;
} public void play() {
compactDisc.play();
}
}

--运行结果

    @Test
public void testCDorDVDPlayer() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CDPlayerConfig.class);
CDorDVDPlayer cDorDVDPlayer = context.getBean("CDorDVDPlayer", CDorDVDPlayer.class);
cDorDVDPlayer.play();
context.close();
}

--事实上@AutoWired注解不仅能够用在构造器之上,还能用在属性的setter方法放,也可以用在其他的任何方法上,其发挥的作用也是完全相同的.假设只有一个bean匹配依赖的话,那么Spring会自动的将这个bean装配起来,否则在idea中将无法通过编译

--如果说没有相关的可匹配bean,Spring会抛出一个异常,为了避免异常的出现,可以将@AutoWired的required属性设置为false

--此时如果没有合适匹配的bean的话,Spring会将这个bean作为无装配状态,但是此时我们就需要在代码中进行null检查,否则这个处于未装配状态的对象很容易出现NullPointerException.实际上在Java依赖注入规范中为我们定义了@Inject注解(@Named注解也是在这之中提供的),其作用和@AutoWired注解相类似.

四.通过Java代码装配Bean
  在很多的情况下我们通过组件扫描和自动装配实现Spring的自动化配置是更为推荐的方式,但是有时候自动化装配的方案行不通,因此需要明确配置Spring.如果想要将第三方库中的组件装配到我们的应用中,那么在这种情况下,是没有办法在它的类上添加@Component和@AutoWired注解的.
--使用Java配置类来实现装配(移除了所有的@Component,@AutoWired,@ComponentScan注解):

 package cd.使用Java配置类进行装配;

 /**
* @author : S K Y
* @version :0.0.1
*/
public interface CompactDisc { //定义一个CD 和DVD的共同接口
/**
* 播放内容
*/
void play();
}
 package cd.使用Java配置类进行装配;

 /**
* @author : S K Y
* @version :0.0.1
*/
public class MyDVD implements CompactDisc {
@Override
public void play() {
System.out.println("现在播放的是我最喜欢的DVD...");
}
}
 package cd.使用Java配置类进行装配;

 /**
* @author : S K Y
* @version :0.0.1
*/
public interface MediaPlayer { //定义一个多媒体播放器接口
/**
* 播放多媒体文件
*/
void play();
}
 package cd.使用Java配置类进行装配;

 /**
* @author : S K Y
* @version :0.0.1
*/
public class CDorDvdPlayer implements MediaPlayer {
private CompactDisc compactDisc; public CDorDvdPlayer(CompactDisc compactDisc) {
this.compactDisc = compactDisc;
} @Override
public void play() {
compactDisc.play();
}
}
 package cd.使用Java配置类进行装配;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration //声明此类为Java配置文件
public class PlayerConfig {
@Bean
public CompactDisc myDVD() {
return new MyDVD();
} @Bean
public MediaPlayer player() {
return new CDorDvdPlayer(myDVD());
}
}
 package cd.使用Java配置类进行装配;

 import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**
* @author : S K Y
* @version :0.0.1
*/
public class PlayerTest {
@Test
public void runWithJavaConfig(){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(PlayerConfig.class);
MediaPlayer player = applicationContext.getBean("player", MediaPlayer.class);
player.play();
}
}

--在默认的情况下@Bean注解返回的bean的ID与方法名是一样的,当然该注解也拥有属性name可以修改当前装配的Bean的ID,当然更为合理的可以使用这样的方式进行拥有相关依赖的bean的装配:

--这种方式的装配,在Spring之中并不会要求这两个相关联的bean必须声明在同一个类之中,甚至,可以是一个声明在XML配置之中,另一个声明在Java类的配置文件之中.

--使用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的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"/>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer">
<constructor-arg ref="myDVD"/>
</bean>
</beans>
     @Test
public void runWithXMLConfig(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("cd/使用Java配置类进行装配/PlayerConfig.xml");
MediaPlayer player = context.getBean("player", MediaPlayer.class);
player.play();
}

--使用XML来装配我们的bean只有一个方法,那就是使用<bean>标签来完成,其中也有两种基本的配置方法可以选择:
  1.<constructor-arg>元素
  2.使用Spring3.0所引入的c-命名空间来完成
--使用c-命名空间完成装配首先需要在Spring的XML配置文件顶部声明其模式,而后在bean标签中使用c:compactDisc-ref属性来完成注入:

 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"/>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:compactDisc-ref="myDVD">
</bean>
</beans>

--观察c-命名空间的组成:

--属性名以“c:”开头,也就是命名空间的前缀。接下来就是要装配的构 造器参数名,在此之后是“-ref”,这是一个命名的约定,它会告诉 Spring,正在装配的是一个bean的引用,这个bean的名字 是compactDisc,而不是字面量“compactDisc”。但是这样的做法还是存在问题,他所引用的构造器参数的名称,我们还可以使用这个参数在构造器之中的位置来进行依赖的注入:

 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"/>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:_0-ref="myDVD">
</bean>
</beans>

--由于在XML中,不允许使用数字作为属性的第一个造福,所以在之前加了一个_来作为前缀.那么如何将字面量属性最为参数赋值给我们的bean呢,修改MyDVD类的结构:

 package cd.使用Java配置类进行装配;

 /**
* @author : S K Y
* @version :0.0.1
*/
public class MyDVD implements CompactDisc {
private String title; //当前这个CD的标题名称
private long time; //当前CD的播放时长 public MyDVD(String title, long time) {
this.title = title;
this.time = time;
} @Override
public void play() {
System.out.println("现在播放的是我最喜欢的DVD,DVD名称为: " + title + " 可播放时长为: " + time + "分钟");
}
}
 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD" c:_0="歌曲串烧" c:_1="120"/>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:_0-ref="myDVD">
</bean>
</beans>
 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD">
<constructor-arg value="歌曲串烧"/>
<constructor-arg value="120"/>
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:_0-ref="myDVD">
</bean>
</beans>

--以上两种配置方式都能够达到我们的目的,但是在需要装配集合的时候,使用c-命名空间无法做到,但是使用<constructor-arg>可以达到我们的目的:

 package cd.使用Java配置类进行装配;

 import java.util.List;

 /**
* @author : S K Y
* @version :0.0.1
*/
public class MyDVD implements CompactDisc {
private String title; //当前这个CD的标题名称
private long time; //当前CD的播放时长
private List<String> musicList; //歌曲清单
public MyDVD(String title, long time) {
this.title = title;
this.time = time;
} public MyDVD(String title, long time, List<String> musicList) {
this.title = title;
this.time = time;
this.musicList = musicList;
} @Override
public void play() {
System.out.println("现在播放的是我最喜欢的DVD,DVD名称为: " + title + " 可播放时长为: " + time + "分钟" +
" 歌曲清单为: " + musicList);
}
}

--如果不想为musicLIst传递任何参数的话,我们可以使用<null/>标签来实现

 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD">
<constructor-arg value="歌曲串烧"/>
<constructor-arg value="120"/>
<constructor-arg><null/></constructor-arg>
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:_0-ref="myDVD">
</bean>
</beans>

--如果想为歌曲清单赋值,那么我们需要使用到<list/>元素将其声明为一个列表:

 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD">
<constructor-arg value="歌曲串烧"/>
<constructor-arg value="120"/>
<constructor-arg>
<list>
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</list>
</constructor-arg>
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" c:_0-ref="myDVD">
</bean>
</beans>

--观察输出实现:

现在播放的是我最喜欢的DVD,DVD名称为: 歌曲串烧 可播放时长为: 120分钟 歌曲清单为: [第一首歌曲, 第二首歌曲, 第三首歌曲, 第四首歌曲, 最厉害的歌曲:我爱Java]

Process finished with exit code 0

--除了java,util,List集合外,我们还可以使用java.util.set在完成,其使用方法与List一致,使用的则是<set/>标签,但是需要注意的是,使用<set/>进行装配的话,那么所有重复的值都会被忽略.

--使用XML进行属性的设置
  如果说我们所提供的构造器是一个无参构造,并且使用getter,setter来实现属性的注入.事实上对于这个类形成所必须的属性,还是会建议使用构造器注入,但是对于那么可选的属性我们则可以选择使用属性注入的方式来完成,而属性的注入与<constructor-arg>相类似,使用的是<property>标签来完成:

 package cd.使用Java配置类进行装配;

 import java.util.List;

 /**
* @author : S K Y
* @version :0.0.1
*/
public class MyDVD implements CompactDisc {
private String title; //当前这个CD的标题名称
private long time; //当前CD的播放时长
private List<String> musicList; //歌曲清单 public MyDVD() {
} public MyDVD(String title, long time) {
this.title = title;
this.time = time;
} public MyDVD(String title, long time, List<String> musicList) {
this.title = title;
this.time = time;
this.musicList = musicList;
} @Override
public void play() {
System.out.println("现在播放的是我最喜欢的DVD,DVD名称为: " + title + " 可播放时长为: " + time + "分钟" +
" 歌曲清单为: " + musicList);
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public long getTime() {
return time;
} public void setTime(long time) {
this.time = time;
} public List<String> getMusicList() {
return musicList;
} public void setMusicList(List<String> musicList) {
this.musicList = musicList;
}
}
 <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD">
<property name="title" value="歌曲串烧"/>
<property name="time" value="120"/>
<property name="musicList">
<list>
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</list>
</property>
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer">
<property name="compactDisc" ref="myDVD"/>
</bean>
</beans>

--Spring为<constructor-arg>提供了c-命名空间作为替代,那么与之相同的,为<property>属性也提供了p-命名空间与之替代:

 <?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: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">
<!--进行bean的装配-->
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"
p:title="歌曲串烧" p:time="120">
<property name="musicList">
<list>
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</list>
</property>
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" p:compactDisc-ref="myDVD">
</bean>
</beans>

--同样的,使用p-命名空间就可能无法顺利的实现集合的装配,没有便利的办法使用p-命名空间来指定一个(或bean引用)的列表,但是我们可以使用Spring util-命名空间来完成一些功能简单的BlankDiscbean:

 <?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:c="http://www.springframework.org/schema/c"
xmlns:util="http://www.springframework.org/schema/util"
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">
<!--进行bean的装配-->
<util:list id="musicList">
<list>
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</list>
</util:list>
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"
p:title="歌曲串烧" p:time="120" p:musicList-ref="musicList">
</bean>
<bean id="player" class="cd.使用Java配置类进行装配.CDorDvdPlayer" p:compactDisc-ref="myDVD">
</bean>
</beans>

--Spring util-命名空间提供了以下的集合类型支持:

五.导入和混合配置
  我们可以进Spring JavaConfig的配置与XML配置相结合,并且在自动装配时,不论是来自哪个配置文件的bean,Spring都能很好的将他们装配到一起.
--在JavaConfig中引用XML配置
  此时,如果觉得XML配置文件已经显得比较笨重,那么我们可以选择将其拆分,我们可以将player的bean采用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"
xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--进行bean的装配-->
<util:list id="musicList">
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</util:list>
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"
p:title="歌曲串烧" p:time="120" p:musicList-ref="musicList">
</bean>
</beans>
 package cd.使用Java配置类进行装配;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration //声明此类为Java配置文件
@ImportResource("classpath:cd/使用Java配置类进行装配/PlayerConfig.xml") //引入XML配置文件
//@Import({PlayerConfig.class}) //引入JavaConfig配置文件
public class PlayerConfig { @Bean("player")
public MediaPlayer player(CompactDisc myDVD) {
return new CDorDvdPlayer(myDVD);
}
}
     @Test
public void runWithXMLConfig(){
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(PlayerConfig.class);
MediaPlayer player = context.getBean("player", MediaPlayer.class);
player.play();
}

--此时我们在JavaConfig配置文件中引入了XML配置文件(需要注意的是在指定XML配置文件的路径的时候,我们需要加上classpath前缀),运行单元测试方法,我们可以得到正确的输出结果,同时除此之外,我们还可以在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"
xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--引入XML配置文件-->
<!-- <import resource="PlayerConfig.xml"/>-->
<!--为确保成功,我们需要开启注解配置的支持-->
<context:annotation-config/>
<!--引入JavaConfig配置文件-->
<bean class="cd.使用Java配置类进行装配.PlayerConfig"/>
<!--进行bean的装配-->
<util:list id="musicList">
<value>第一首歌曲</value>
<value>第二首歌曲</value>
<value>第三首歌曲</value>
<value>第四首歌曲</value>
<value>最厉害的歌曲:我爱Java</value>
</util:list>
<bean id="myDVD" class="cd.使用Java配置类进行装配.MyDVD"
p:title="歌曲串烧" p:time="120" p:musicList-ref="musicList">
</bean>
</beans>
 package cd.使用Java配置类进行装配;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author : S K Y
* @version :0.0.1
*/
@Configuration //声明此类为Java配置文件
//@ImportResource("classpath:cd/使用Java配置类进行装配/PlayerConfig.xml") //引入XML配置文件
//@Import({PlayerConfig.class}) //引入JavaConfig配置文件
public class PlayerConfig {
@Bean("player")
public MediaPlayer player(CompactDisc myDVD) {
return new CDorDvdPlayer(myDVD);
}
}
     @Test
public void runWithXMLAndJavaConfig(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("cd/使用Java配置类进行装配/PlayerConfig.xml");
MediaPlayer player = context.getBean("player", MediaPlayer.class);
player.play();
context.close();
}

--这里需要说明的是,为了确保在XML配置文件中正确应用JavaConfig中的Bean,我们需要在XML中开启注解配置的支持,即需要使用<context:annotation-config/>标签实现注解配置的支持.当然,你也可以选择创建一个XML配置文件不进行任何的配置,但是用来将其他的各类配置文件装配到一块,这取决于你的编程习惯.在Spring的官方建议中,建议我们去使用基于注解的自动装配以避免显示配置带来的维护成本.

Spring学习(二)--装配Bean的更多相关文章

  1. spring学习总结——装配Bean学习二(JavaConfig装配bean)

    通过Java代码装配bean 前言:上面梳理了通过注解来隐式的完成了组件的扫描和自动装配,下面来学习下如何通过显式的配置的装配bean: 使用场景:比如说,你想要将第三方库中的组件装配到你的应用中,在 ...

  2. spring学习总结——装配Bean学习三(xml装配bean)

    通过XML装配bean Spring现在有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择了.不过,鉴于已经存在那么多基于XML的Spring配置,所以理解如何在Spring中使用 ...

  3. spring学习总结——装配Bean学习一(自动装配)

    一.Spring配置的可选方案 Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系.但是,作为开发人员,你需要告诉Spring要创建哪些bean并且如何将其装配在一起.当描 ...

  4. Spring学习笔记—装配Bean

    在Spring中,对象无需自己负责查找或创建与其关联的其他对象.相反,容器负责把需要相互协作的对象引用赋予各个对象.创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入的本质. ...

  5. spring学习总结——装配Bean学习四(导入和混合配置)

    情景:在典型的Spring应用中,我们可能会同时使用自动化和显式配置(JavaConfig)或者XML配置,幸好在Spring中,这些配置方案都不是互斥的.你尽可以将JavaConfig的组件扫描和自 ...

  6. Spring学习之装配Bean

    通过注解配置的bean,默认是单例 @Autowired private CodeTypeService codeTypeService; 测试:在Controller层调用Service层对象Cod ...

  7. #Spring实战第二章学习笔记————装配Bean

    Spring实战第二章学习笔记----装配Bean 创建应用对象之间协作关系的行为通常称为装配(wiring).这也是依赖注入(DI)的本质. Spring配置的可选方案 当描述bean如何被装配时, ...

  8. spring实战二之Bean的自动装配(非注解方式)

    Bean的自动装配 自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bea ...

  9. Spring总结 1.装配bean

    本随笔内容要点如下: 依赖注入 Spring装配bean的方式 条件化装配 一.依赖注入 我理解的依赖注入是这样的:所谓的依赖,就是对象所依赖的其他对象.Spring提供了一个bean容器,它负责创建 ...

随机推荐

  1. EasyUi 表格自适应宽度

    第一次接触EasyUi想要实现表格宽度自适应,网上找了好多文章,都没有实现,有网友实现了可是自己看不懂.可能是太简单高手都懒得分享,现在把自己的理解和实现记录一下,希望可以帮到向自己一样的菜鸟,步骤如 ...

  2. Docker备份与迁移

    容器保存为镜像 通过以下命令将容器保存为镜像: docker commit [-m="提交的描述信息"] [-a="创建者"] 容器名称|容器ID 生成的镜像名 ...

  3. hr员工数据分析(实战)

    hr员工数据分析项目实战 (数据已脱敏) 背景说明 某公司最近公司发生多起重要员工意外离职.部分员工工作缺乏积极性等问题,受hr部门委托,开展数据分析工作. 经与hr部门沟通,确定以下需求: 制定数据 ...

  4. SPOJ - DQUERY (主席树求区间不同数的个数)

    题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数. 解题思路:从左向右一个一 ...

  5. cx_Oracle python模块安装

    1. 需要从oracle网站下载一下两个包 instantclient-basic-linux.x64-11.2.0.4.0.zip instantclient-sdk-linux.x64-11.2. ...

  6. j函数 判断以 什么开头

    1.str.charAt(index) 返回字符串中指定位置的字符. str 是字符串  我们要将获得的数据 转化为字符串 var code = res.statusCode.toString(); ...

  7. 函数柯里化(Currying)小实践

    什么是函数柯里化 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.这个技术由 Ch ...

  8. [POJ 1390] Blocking

    问题描述 Some of you may have played a game called 'Blocks'. There are n blocks in a row, each box has a ...

  9. LRU management

    LRU management 字典树用来查找值,实现map<string,int>操作 tips:tot必须从一开始QAQ #include<bits/stdc++.h> us ...

  10. Quick Notes

    激励 每当在书中读及那些卑微的努力,都觉得感动且受震撼.也许每个人在发出属于自己的光芒之前,都经历了无数的煎熬,漫长的黑夜,无尽的孤独,甚至不断的嘲讽和否定,但好在那些踮脚的少年,最后都得到了自己想要 ...