Spring装配Bean

Spring 实战第二章

Posted by 刘知安 on 2019-12-20
文章目录
  1. 1.Spring配置的三种方案
    1. 1.1 自动装配
    2. 1.2 在Java中显式配置
    3. 1.3 在XML中显式配置
  2. 2. 混合装配
  3. 3. 总结

1.Spring配置的三种方案

1.1 自动装配

  1. 首先,需要将Bean类添加@Component注解,便于Spring进行扫描(默认是关闭的)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Component
    public class BeyondCD implements CD {
    private String title = "Beyond合集唱片";
    private String artist = "Beyond";

    @Override
    public String play() {
    return this.title+"播放中...作者: "+this.artist;
    }
    }
  2. 其次,需要定一个Java配置类来开启组件扫描,添加@Configuration@ComponentScan注解,这样会默认扫描同一包下所有带有@Component注解的Bean类。
    1
    2
    3
    4
    @Configuration
    @ComponentScan
    public class CDPlayerConfig {
    }
  3. 最后我们可以用上述配置类来开启一个应用/测试
    这里是一个测试的例子,要加上注解@ContextConfiguration(classes = XXX.class),其中XXX就是上述定义的Java配置类。@Autowired注解表明会自动装配Bean
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = CDPlayerConfig.class)
    public class CDPlaerTest {

    @Autowired
    private CD cd;

    @Autowired
    private Player player;

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

    @Test
    public void play() {
    String res=player.play();
    Assert.assertEquals("Beyond合集唱片播放中...作者: Beyond",res);
    }

    }
    上面的@RunWith,Assert.assertNotNull()是JUnit中的东西,在这里影响不大,注解@Autowired才是关键。

1.2 在Java中显式配置

1.首先,我们同样需要写一个Java配置类来手动进行显式地装配Bean。每创建一个Bean,都要写一个带有@Bean注解的方法,返回一个Bean对象,Spring默认会生成一个单例的Bean对象,在下次调用被@Bean注解修饰的方法时,只会返回这个创建好的Bean对象,而不会再创建一个新的。大概类似这样,其实就是一种JAVA的“配置文件”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
public class CDPlayerConfig {

// 显式生成一个bean,bean的ID默认为方法名,但也可以指定参数name
@Bean(name = "myBeyondCD")
public CD beyondCD()
{
return new BeyondCD();
}

// 方法1:
@Bean
public Player cdPlayer()
{
// 这里只会返回之前创建好的bean对象,不会再创建一个
return new CDPlayer(beyondCD());
}
// 方法2:
//@Bean
//public Player cdPlayer(CD cd)
//{
// return new CDPlayer(cd);
//}


}

1.3 在XML中显式配置

这个就比较好理解了,其实和Java类配置的思路是一样的,只不过XML配置的方式更“死”,在JAVA配置类中我们甚至可以通过各种逻辑去对Bean进行各种操作,而XML中就很难做到这一点。

1
2
3
4
5
6
7
8
9
10
<?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="myBeyondCD" class="com.liuzhian.soundsys.BeyondCD"/>
<bean id="myCDPlayer" class="com.liuzhian.soundsys.CDPlayer">
<constructor-arg ref="myBeyondCD"/>
</bean>
</beans>

还有一种所谓的c命名空间声明方式,这个虽然看上去简洁,但是我觉得问题蛮多,它甚至会需要在xml的属性中输入Java的Bean类中的方法参数名字!这真是奇怪,形参名字不是应该被编译器优化吗?为什么这里还保留?的确好像这个c命名空间声明方式是在Spring 3中使用的,现在貌似不鼓励使用了。

于是乎,应用代码可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {

//1.创建spring容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");

// @Autowired
private CD cd;

// @Autowired
private Player player;

@Test
public void cdShouldNotBeNull() {
//2.从容器中获取bean实例
cd=(CD) ctx.getBean("myBeyondCD");
Assert.assertNotNull(cd);
}

@Test
public void play() {
//2.从容器中获取bean实例
player=(Player) ctx.getBean("myCDPlayer");

String res = player.play();
Assert.assertEquals("Beyond合集唱片播放中...作者: Beyond", res);
}

}

2. 混合装配

Spring也支持XML和Java配置类交叉混合配置,Java配置类中可以通过@ImportResource()注解引用XML配置文件,在XML配置文件中直接通过<bean>标签引用,只不过现在标签的class属性的取值不是具体的Bean类,而是Java配置文件的类。具体的这里不记录了,以后用到了再看。

3. 总结

装配方式的选取原则:

  1. 尽可能使用自动化配置,以避免显式配置所带来的维护成本。
  2. 如果确实需要显式配置Spring的话,应该优先选择基于Java的配置,它比基于XML的配置更加强大、类型安全并且易于重构。
  3. 最后考虑使用XML配置