spring Bean装配的几种方式简单介绍

Spring容器负责建立应用程序中的bean同时经过ID来协调这些对象之间的关系。做为开发人员,咱们须要告诉Spring要建立哪些bean而且如何将其装配到一块儿。java

spring中bean装配有两种方式spring

  • 隐式的bean发现机制和自动装配
  • 在java代码或者XML中进行显示配置

固然这些方式也能够配合使用。安全

咱们测试代码以下ide

CompactDisc和MediaPlayer是两个接口 其中MediaPlayer的构造方法参数类型为CompactDisc。
咱们主要测试CompactDisc和MediaPlayer的实现有没有注入进来,同时MediaPlayer接口对于CompactDisc的依赖有没有知足
package com.zcs;

import com.zcs.service.CompactDisc;
import com.zcs.service.MediaPlayer;
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 static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;

@RunWith(SpringJUnit4ClassRunner.class)
//XML配置
//@ContextConfiguration(locations ="spring-config.xml")
//Java代码配置
@ContextConfiguration(classes =CDPlayerConfig.class)
public class CDPlayerTest {
    @Autowired
    private CompactDisc cd;
    @Autowired
    private MediaPlayer player;
    @Test
    public void cdShouldNotBeNull(){
        assertNotNull(cd);
    }
    @Test
    public void play(){
        assertEquals("Playing 哎呦不错哦 by 周杰伦",player.play());
    }

}

 

一、自动化装配测试

Spring从两个角度来实现自动化装配:this

组件扫描(ComponentScan):自动发现应用上下文中所建立的beanspa

自动装配(Autowired):自动知足bean之间的依赖code

CompactDisc接口类和实现类:component

public interface CompactDisc {
    String play();
}
@Component
public class SgtPeppers implements CompactDisc { private String title="哎呦不错哦"; private String artist="周杰伦"; @Override public String play() { return "Playing "+title+" by "+artist; } }

MediaPalyer接口类和实现类xml

public interface MediaPlayer {
    String play();
}
@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd ;
    @Autowired
    public CDPlayer(CompactDisc cd){
        this.cd=cd;
    }
    @Override
    public String play(){
      return cd.play();
    }
}

 

配置类CDPlayerConfig:

@Configuration
@ComponentScan
public class CDPlayerConfig {

}

 

@ComponentScan做用是扫描带有@Component注解的类,并为其建立bean。默认是扫描同一包下的类,固然也能够加入参数,指定包名。

如@ComponentScan(basePackages={"com.zcs"})或者@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class})(即这些类所在的包)

@Autowired知足自动依赖装配,能够做用在任何方法上面。

XML形式的自动装配则修改测试类@ContextConfiguration,改为加载spring-config.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">
    <bean id="compactDisc" class="com.zcs.impl.SgtPeppers"></bean>
    <bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
        <constructor-arg ref="compactDisc"></constructor-arg>
    </bean>
    <context:component-scan base-package="com.zcs">
</beans>

 二、显示bean装配

当想要将第三方库中的组件装配到你的应用中,在这种状况下是没有办法在它的类上面添加@Component和@Autowired注解的,所以就不能使用自动化装配的方案。

 只能选择java代码或者xml显示配置

首先能够把两个实现类上的@Component,还有配置类中的@ComponentScan,CDPlayer类中方法上的@Autowired注解去掉。

这个时候测试应该都通不过。

Java代码方式:修改CDPlayerConfig配置类为:

@Configuration
public class CDPlayerConfig {
    @Bean
    public CompactDisc sgtPeppers(){
        return new SgtPeppers();
    }
    @Bean
    public MediaPlayer getCDPlayer(){
        return new CDPlayer(sgtPeppers());
    }
   //@Bean
    //public MediaPlayer getCDPlayer(CompactDisc compactDisc){ // return new CDPlayer(compactDisc); //}
}

 

 再运行测试应该会经过了,解释下 @Bean注解告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终生成bean实列的逻辑。

 第二个方法故意写的奇怪一点,看起来CompactDisc是经过调用sgtPeppers()方法获得的,但并不是如此,Spring会拦截对sgtPeppers方法的调用,转而从上下文中直接获取该方法所建立的bean,而不是每次都对其进行实际的调用。

好比:再添加一个方法(测试会通不过)

   @Bean
    public MediaPlayer anotherCDPlayer() {
        return new CDPlayer(sgtPeppers());
    }

 

这两个方法依赖注入的CompactDisc将会是同一个bean。

固然经过状况下用注释的方法更容易理解一点。

XML方式

首先CDPlayerTest为XML方式,同时修改spring-config.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">
    <bean id="compactDisc" class="com.zcs.impl.SgtPeppers"></bean>
    <bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
        <constructor-arg ref="compactDisc"></constructor-arg>
    </bean>
    <context:component-scan base-package="com.zcs"/>
</beans>

 

组件扫描方式的配置不去掉也是没影响的。

补充:

复杂一点的构造方法

修改SgtPeppers的构造方法

public class SgtPeppers implements CompactDisc {
    private String title="哎呦不错哦";
    private String artist="周杰伦";
    private List<String> tracks=new ArrayList<>();

    public SgtPeppers(String title, String artist, List<String> tracks) {
        this.title = title;
        this.artist = artist;
        this.tracks = tracks;
    }

    @Override
    public String play() {
        return "Playing "+title+" by "+artist;
    }
}

 

同时修改spring-config.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">
    <bean id="compactDisc" class="com.zcs.impl.SgtPeppers">
        <constructor-arg index="0" value="雪狼湖"/>
        <constructor-arg index="1" value="张学友"/>
        <constructor-arg index="2">
            <list>
                <value>不老的传说</value>
                <value>爱是永恒</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
        <constructor-arg ref="compactDisc"></constructor-arg>
    </bean>
    <context:component-scan base-package="com.zcs"/>
</beans>

 

还有属性注入<property>,c和p命名空间使用就不细说了。对于xml的配置通常在java代码中也会有对应的配置。但显示配置用java代码会类型安全一点

 

 参考:spring实战第4版

相关文章
相关标签/搜索