spring装配

装配

自动装配

装配文件

  • 装配文件是java文件,必须要有标签@Configuration和@ComponentScan,该类需要放在被扫描的其他类文件的同级目录
  • 如果装配文件不放到被扫描文件的同级目录,可以通过@ComponentScan("${packagename}"),来扫描指定包
  • @ComponentScan也可以指定basePackages或basePackageClasses,尤其是后者可以通过结合标记接口文件的方式来避免出错
package soundsystem;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @Description CdPlayerConfig
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
@Configuration
@ComponentScan
public class CdPlayerConfig {
}

被装配文件

package soundsystem;

/**
 * @Description CompactDisc
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
public interface CompactDisc {
    void play();
}
package soundsystem;

import org.springframework.stereotype.Component;

/**
 * @Description SgtPeppers
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
@Component
public class SgtPeppers implements CompactDisc {
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artist = "The Beatles";

    @Override
    public void play() {
        System.out.print("Playing " + title + " by " + artist);
    }
}
package soundsystem;

/**
 * @author cooper
 */
public interface MediaPlayer {
    void play();
}
package soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Description CDPlayer
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
@Component
public class CdPlayer implements MediaPlayer{
    @Autowired
    private CompactDisc disc;
    @Override
    public void play() {
        disc.play();
    }
}

验证

package soundsystem;

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration(classes = CdPlayerConfig.class)
public class SgtPeppersTest {
    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Autowired
    private CompactDisc cd;

    @Before
    public void before() {
        log.enableLog();
    }

    @Test
    public void cdShouldNotBeNull() {
        TestCase.assertNotNull(cd);
    }

    @Test
    public void play() {
        player.play();
        TestCase.assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }
}

这里的SystemOutRule需要开启enableLog(),来接收输出,上边的两个标签也至关重要

  • pom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.cooper.spring.in.action</groupId>
        <artifactId>assembling</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>14</maven.compiler.source>
            <maven.compiler.target>14</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <spring.version>5.3.4</spring.version>
            <junit.version>4.12</junit.version>
            <system.rules.version>1.19.0</system.rules.version>
        </properties>
    
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.github.stefanbirkner</groupId>
                <artifactId>system-rules</artifactId>
                <version>${system.rules.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
    

javaconfig

装配文件

  • 同样的@Configuration表示这是一个装配文件
  • 这的@Bean用来创建单例bean,方法名就是单例的Id
  • @Bean创建出来的单例Id是按照类型传给别的方法的,并不要求参数名相同
package soundsystem;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @Description CdPlayerConfig
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
@Configuration
public class CdPlayerConfig {
    @Bean
    public CompactDisc compactDisc() {
        return new SgtPeppers();
    }

    @Bean
    public CdPlayer cdPlayer(CompactDisc compactDisc) {
        return new CdPlayer(compactDisc);
    }
}

被装配文件

package soundsystem;

/**
 * @Description CompactDisc
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
public interface CompactDisc {
    void play();
}
package soundsystem;


/**
 * @Description SgtPeppers
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
public class SgtPeppers implements CompactDisc {
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artist = "The Beatles";

    @Override
    public void play() {
        System.out.print("Playing " + title + " by " + artist);
    }
}
package soundsystem;

/**
 * @author cooper
 */
public interface MediaPlayer {
    void play();
}
package soundsystem;

/**
 * @Description CDPlayer
 * @Author sunzhilong
 * @Since 2021/04/05
 **/
public class CdPlayer implements MediaPlayer {
    private CompactDisc disc;

    public CdPlayer(CompactDisc disc) {
        this.disc = disc;
    }

    @Override
    public void play() {
        disc.play();
    }
}
  • 可以看到被装配文件少了@Autowired和@Component标签

验证

package soundsystem;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration(classes = CdPlayerConfig.class)
public class CDPlayerTest {

    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Before
    public void before() {
        log.enableLog();
    }

    @Test
    public void play() {
        player.play();
        assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }
}
  • 这里依然用了@Autowired来为变量注入,也能成功,让人感到奇怪,看来@SpringJUnit4ClassRunner标签还是很厉害的

xml装配

引用方式

引用方式是最常见的一种引用方式

被装配文件
package soundsystem;

public interface MediaPlayer {
  void play();
}
package soundsystem;

public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}
package soundsystem;

public interface CompactDisc {
    void play();
}
package soundsystem;

public class SgtPeppers implements CompactDisc {
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artist = "The Beatles";

    @Override
    public void play() {
        System.out.print("Playing " + title + " by " + artist);
    }
}
验证
package soundsystem;

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration
public class ConstructorArgReferenceTest {
    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Before
    public void before() {
        log.enableLog();
    }

    @Test
    public void play() {
        player.play();
        TestCase.assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }
}
配置文件

验证时需要相应的xml文件,注意文件在测试的resources中的soundsystem目录下,以ConstructorArgReferenceTest-context.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="compactDisc" class="soundsystem.SgtPeppers"/>

    <bean id="cdPlayer" class="soundsystem.CDPlayer">
        <constructor-arg ref="compactDisc"/>
    </bean>

</beans>

很显然测试类中的@ContextConfiguration标签起到了查找xml所在位置的能力,默认是同目录的位置的对应测试类名开头以-context结尾的xml文件,如果不在同目录下将会报异常

407, 2021 12:32:16 上午 org.springframework.test.context.support.AbstractContextLoader generateDefaultLocations
信息: Could not detect default resource locations for test class [soundsystem.ConstructorArgReferenceTest]: no resource found for suffixes {-context.xml}.
407, 2021 12:32:16 上午 org.springframework.test.context.support.AnnotationConfigContextLoaderUtils detectDefaultConfigurationClasses
信息: Could not detect default configuration classes for test class [soundsystem.ConstructorArgReferenceTest]: ConstructorArgReferenceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.

java.lang.IllegalStateException: DelegatingSmartContextLoader was unable to detect defaults, and no ApplicationContextInitializers or ContextCustomizers were declared for context configuration attributes [[ContextConfigurationAttributes@6b57696f declaringClass = 'soundsystem.ConstructorArgReferenceTest', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']]

引用值方式

被装配文件
package soundsystem;

public interface MediaPlayer {
  void play();
}
package soundsystem;

public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}
package soundsystem;

public interface CompactDisc {
    void play();
}
package soundsystem;

public class BlankDisc implements CompactDisc {
    private String title;
    private String artist;

    public BlankDisc(String title, String artist) {
        this.title = title;
        this.artist = artist;
    }

    @Override
    public void play() {
        System.out.print("Playing " + title + " by " + artist);
    }
}
验证
package soundsystem;

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration
public class ConstructorArgValueTest {
    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Before
    public void before() {
        log.enableLog();
    }


    @Test
    public void play() {
        player.play();
        TestCase.assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }
}
配置文件

配置文件规则要求和上述相同

<?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="compactDisc"
          class="soundsystem.BlankDisc">
        <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band"/>
        <constructor-arg value="The Beatles"/>
    </bean>

    <bean id="cdPlayer"
          class="soundsystem.CDPlayer">
        <constructor-arg ref="compactDisc"/>
    </bean>

</beans>

c命名空间引用

被装配文件

和直接引用Id方式相同

验证
package soundsystem;

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration
public class CNamespaceReferenceTest {
    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Before
    public void before() {
        log.enableLog();
    }

    @Test
    public void play() {
        player.play();
        TestCase.assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }

}
配置文件

既然是C命名空间就要有xmlns:c=“http://www.springframework.org/schema/c”

<?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 id="compactDisc" class="soundsystem.SgtPeppers"/>

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

</beans>

p命名空间引用

被装配文件
package soundsystem;

public class BlankDisc implements CompactDisc {
    private String title;
    private String artist;

    public BlankDisc(String title, String artist) {
        this.title = title;
        this.artist = artist;
    }

    @Override
    public void play() {
        System.out.print("Playing " + title + " by " + artist);
    }
}
package soundsystem.properties;
import org.springframework.beans.factory.annotation.Autowired;

import soundsystem.CompactDisc;
import soundsystem.MediaPlayer;

public class CDPlayer implements MediaPlayer {
  private CompactDisc compactDisc;

  @Autowired
  public void setCompactDisc(CompactDisc compactDisc) {
    this.compactDisc = compactDisc;
  }

  @Override
  public void play() {
    compactDisc.play();
  }
}
验证
package soundsystem;

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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)
@ContextConfiguration
public class PNamespaceRefTest {
    @Rule
    public final SystemOutRule log = new SystemOutRule();

    @Autowired
    private MediaPlayer player;

    @Before
    public void before() {
        log.enableLog();
    }

    @Test
    public void play() {
        player.play();
        TestCase.assertEquals(
                "Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles",
                log.getLog());
    }

}
配置文件

配置文件中要与p命名空间的规范引入:xmlns:p=“http://www.springframework.org/schema/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: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 id="compactDisc" class="soundsystem.BlankDisc">
        <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band"/>
        <constructor-arg value="The Beatles"/>
    </bean>

    <bean id="cdPlayer" class="soundsystem.properties.CDPlayer">
        <property name="compactDisc" ref="compactDisc"/>
    </bean>

</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值