Spring -- 装配Bean(Part 1/3)

《Spring 实战》 读书笔记 第二章

Spring配置的可选方案

  • 隐式的bean发现机制和自动装配(本章)
  • 在Java中进行显示配置
  • 在XML中进行显示配置

尽可能地使用自动配置的机制。显示配置越少越好(有些源码不是你来维护的,而当你需要为这些代码配置bean的时候,需要显示配置bean)。推荐使用类型安全并且比xml更加强大的JavaConfig。最后,只有当你想要使用便利的xml命名空间,并且在JavaConfig中没有同样的实现时,才使用xml。

自动化装配Bean

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

  • 组件扫描:Spring 会自动发现应用上下文所创建的bean
  • 自动装配:Spring自动满足bean之间的依赖

组件扫描和自动装配组合在一起就能发挥强大的威力,能够将你的显示配置降低到最少。

创建可被发现的bean

package com.loveqrc;

public interface CompactDisc {
    void play();
}
package com.loveqrc;


import org.springframework.stereotype.Component;

@Component
public class SgtPeppers implements CompactDisc {
    String author = "梁静茹";
    String title = "Today";

    @Override
    public void play() {
        System.out.println("Playing" + title + "by" + author);
    }
}

@Component表明该类会作为组件类,并且告知Spring要为这个类创建bean

但是组件扫描默认是不启动的,需要显示配置Spring。从而去寻找@Component组件,并为其创建bean。

package com.loveqrc;
@Configuration
@ComponentScan
public class CDPlayerConfig {
}

@ComponentScan注解启用组件扫描,如果不配置@ComponentScan的话,默认会扫描和配置类相同的包,因为CDPlayerConfig 位于com.loveqrc包下,因此Spring将会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类,并且其创建一个bean。

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {

    @Autowired
    private CompactDisc cd;

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

CDPlayerTest 使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文,@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置,因为CDPlayerConfig包含@ComponentScan,最终应用上下文应该包含CompactDisc Bean。@Autowired将CompactDisc Bean注入到代码中。
上面的代码将通过测试。

为组件Bean命名

Spring会给每个Bean一个Id,在前面的例子中,尽管没有为SgtPeppers 设置Id,但Spring会根据类名为其制定一个Id,默认是第一个字母变为小写即(sgtPeppers)

如果想为这个bean设置不同的Id,只需将期望的ID作为值传递给@Component,例如

@Component("MySong")
public class SgtPeppers implements CompactDisc {
}

还有另外一种为bean命名方式,这种方式是不使用@Component注解,而是使用Java依赖注入规范中的@Name来设置ID,Spring支持将@Name作为@Component注解的替换方案,但是在Spring中语义不强,不推荐。

设置组件扫描的基础包

@ComponentScan的默认规则是以配置类所在的包作为基础包来扫描组件,但是如果你想扫描多个基础包或扫描不同的包,那该怎么办?

你可以在@ComponentScan的value属性中指明包的名称

@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig {
}

如果你想更加清晰地表明你所设置的是基础包,那么可以通过basePackages进行配置

@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig {
}

basePackages支持复数的形式,可以设置多个基础包

@Configuration
@ComponentScan(basePackages = {"soundsystem","video"})
public class CDPlayerConfig {
}

设置基础包这种方法是不太安全的,一旦重构代码,那么你所指定的基础包就很有可能出错(因为设置基础包是String类型表示),除了将包设置为简单的String类型之外,@ComponentScan还提供了另外一种方法,那就是将其指定为包中所包含的类或接口。

@Configuration
@ComponentScan(basePackageClasses = {CDPlayer.class})
public class CDPlayerConfig {
}

basePackages 属性被替换成basePackageClasses ,不再使用String类型的名称来指定包,为basePackageClasses 属性所设置的数组中包含了类,这些类所在的包将会作为组件扫描的基础包

通过为bean添加注解实现自动装配

自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文寻找匹配某个bean需求的其他bean,为了声明要进行自动装配,可以借助@Autowired注解。

@Component
public class CDPlayer implements MediaPlayer {
  private CompactDisc cd;

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

  public void play() {
    cd.play();
  }

}

@Autowired注解不仅能够用在构造器上,还能使用在类的任何方法上。

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

   /* @Autowired
    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }*/

    public void play() {
        cd.play();
    }

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

}

你可能感兴趣的:(Spring -- 装配Bean(Part 1/3))