【Spring实战】第2章 装配Bean

组件扫描

使用 <bean> 标签一个个将类定义到配置文件很麻烦,可以启用组件扫描,自动扫描类注册到上下文中。

@Component:哪些类是要扫描的

/**
 * 如果启用了组件自动扫描,这个注解就是告诉 Spring 要创建 Bean。
 * 在 Spring 的上下文中有一个 Bean ID,默认是类名首字母小写,如 sgtPeppers。
 * 使用 @Component("newName") 配置自定义的新名字
 */
@Component
public class SgtPeppers implements CompactDisc {}

解答为什么@Autowired使用在接口上而不是实现类上

如果接口 CompactDisc 的实现类有 2 个,那么 @Autowire 的时候怎么判断要用哪个呢?

使用 @Component("newName") 自定义名字,然后使用 @Autowired 和 @Qualifier("newName") 来指定。

@ComponentScan:启动组件扫描

/*
@ComponentScan 默认扫描配置类所在的包。
使用 @ComponentScan(basePackages = "soundsystem") 可以扫描指定包。还可以指定类所在的包。
 */
@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig {
}

或者在 XML 文件里面启动:

<context:component-scan base-package="soundsystem"/>

Spring Test 自动创建上下文

如果只用 Junit,每次创建测试类,都要 new 上下文,很麻烦。使用 SpringTest 自动创建上下文。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.0.7.RELEASE</version>
</dependency>
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;

@RunWith(SpringJUnit4ClassRunner.class) // 自动创建 Spring 应用上下文
@ContextConfiguration(classes = CDPlayerConfig.class) // 到 CDPlayerConfig 加载配置
public class AutoScanTest {
    @Autowired
    private CompactDisc cd;
    @Test
    public void test1() {
        cd.play();
    }
}

自动装配

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    /*
    表明 Spring 创建 CDPlayer 时,会使用这个构造器。
    不论是构造器,还是 Setter,Spring 都会尝试满足方法上的参数依赖,将 Bean 装配进来。
    如果没有匹配的 Bean,会抛异常,可使用 @Autowired(required = false)
     */
    @Autowired
    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }
    @Autowired
    public void setCompactDisc(CompactDisc cd) {
        this.cd = cd;
    }
    public void play() {
        cd.play();
    }
}

Java 装配 Bean

@Configuration
@ComponentScan
public class CDPlayerConfig {
    /*
    要将第三方的组件装配到应用中
    @Bean(name="newName") 指定名字
     */
    @Bean
    public CompactDisc sgtPeppers() {
        return new SgtPeppers();
    }
    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc) {
        // 可以通过构造器或 Setter 方法注入依赖
        CDPlayer cdPlayer = new CDPlayer(compactDisc);
        cdPlayer.setCompactDisc(compactDisc);
        return cdPlayer;
    }
}

使用 XML 装配 Bean

<?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"
       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/beans/spring-util.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
@ContextConfiguration(locations = {"classpath*:/soundsystem.xml"}) // classpath* 指在 classpath 和 jar 包中找

构造器注入

<!-- 使用 c 命名空间,c:_0 表示第一个参数的值
    <bean id="compactDisc" class="soundsystem.BlankDisc" c:_0="qiqi" c:_1="caca">
    <constructor-arg>
        <list>
            <value>v1</value>
            <value>v2</value>
        </list>
    </constructor-arg>
</bean>-->

<bean id="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value="haha"/>
    <constructor-arg value="xixi"/>
    <!-- 参数类型是 List<String>,将列表设置为 null
    <constructor-arg><null/></constructor-arg>-->
    <constructor-arg>
        <!-- 还有 <Set> 标签 -->
        <list>
            <value>v1</value>
            <value>v2</value>
            <!-- 类型是 List<Bean>,要实现 Bean 引用列表的装配
            <ref bean="sgtPeppers"/>
            -->
        </list>
    </constructor-arg>
</bean>
<!-- c:_0-ref 表示第一个参数 -->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc"/>

Setter 注入

<bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc"/>

<!--<bean id="compactDisc" class="soundsystem.BlankDisc">
    <property name="title" value="haha"/>
    <property name="tracks">
        <list>
            <value>v1</value>
            <value>v2</value>
        </list>
    </property>
</bean>-->

<bean id="compactDisc" class="soundsystem.BlankDisc" p:title="haha" p:tracks-ref="trackList"/>

<!-- 使用 util 命令来简化列表-->
<util:list id="trackList">
   <value>v1</value>
   <value>v2</value>
</util:list>

将配置组合起来

@Configuration
@Import(CDConfig.class)
@ImportResource("classpath:cd-config.xml")
<bean class="soundsystem.CDConfig"/>
<import resource="soundsystem.xml"/>
posted @ 2023-05-10 17:32  seolas  阅读(6)  评论(0编辑  收藏  举报