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:我的个人博客 强哥

posted @ 2020-04-08 22:31  泛舟瓦尔登湖  阅读(106)  评论(0编辑  收藏  举报