自动装配 bean

创建可被发现的 Bean

CD 需要注入到 CD 播放器中进行播放,这样 CD 播放器才能正常运行。

CD 接口类
package soundsystem;

public interface CompactDisc {

    void play();
}
CD接口的一个实现
package soundsystem;

import org.springframework.stereotype.Component;

@Component
public class SgtPepper implements CompactDisc {

    private String title = "Sgt. Pepper's Loney Herts Club Band";
    private String artist = "The Beatles";

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

这个 CD 的实现类使用了@Component注解,这个注解表明该类会作为组件类,并告知 Spring 要为这个类创建 Bean。

组件扫描

前面 CD 的实现类添加了注解,会作为一个组件类,但是组件扫描默认是不开启的,我们需要显式地配置一下 Spring,从而命令它去寻找带有@Component注解的类,并为其创建 bean。

package soundsystem;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {
}

注解@ComponentScan能够在 Spring 中启用组件扫描,如果没有其它配置的话,@ComponentScan默认会扫描与配置类相同的包,Spring 会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类。

为组件扫描的 bean 命名

Spring 应用上下文中所有的 bean 都会给定一个 ID,前面虽然我们没有明确地为 SgtPeppers bean 指定 ID,但是 Spring 会根据类名为其指定一个 ID,默认将类名的第一个字母变为小写,也就是sgtPeppers

如果要为 bean 设置不同的 ID,可以将ID 作为值传给@Component注解。

@Component("loneyHeartClub")
public class SgtPepper implements CompactDisc {
   ...
}

设置组件扫描的基础包

前面的代码中,我们没有为@ComponentScan设置任何属性,所以它会以配置类所在包作为基础包来扫描组件。但是如果我们想将配置类放在单独的包中,使其与其它应用代码区分开来,那默认的就不行了。

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

或者显式地指定 basePackages:

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

可以同时指定多个基础包:

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

上面的基础包的指定都是以字符串的形式,但是这种方法是类型不安全的,如果你重构代码的话,可能就会出现错误。除了将包设置为简单的字符串类型外,@ComponentScan还提供了另外一种方法,那就是将其指定为包中所包含的类或接口:

@Configuration
@ComponentScan(basePackageClasses = { SgtPepper.class, DVDPlayer.class})
public class CDPlayerConfig {
}

上面指定的类有些是组件类,为了更好区分,可以在这些包中创建一个空的扫描标记接口,然后使用这个接口类指定扫描包。

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

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

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

@Component
public class CDPlayer implements MediaPlayer {

    private CompactDisc cd;

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

    @Override
    public void play() {
    }
}

上面代码在构造器上添加了@Autowired注解,这表明当 Spring 创建 CDPlayer bean 的时候,会通过这个构造器来进行实例化并且传入一个可设置给 CompactDisc 类型的 bean。

@Autowired不仅可以用在构造器上,实际上它可以用在任何方法上。

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

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

Spring 在尝试满足方法参数上所声明的依赖时,如果有且只有一个 bean(也就是一个实现)能匹配依赖需求的话,那么这个 bean 将会被包装进来。

如果没有匹配的 bean,那么在应用上下文创建的时候,Spring 会抛出一个异常,为了避免这个异常,你可以设置属性 required 为 false:

@Autowired(required = false)
public void insertDisc(CompactDisc cd) {
    this.cd = cd;
}

默认是为 true 的,当设置为 false 的时候,在代码要记得在使用时判空。

如果有多个备案都满足依赖关系的话,Spring 会抛出一个异常,这表明没有明确指定要选择哪个 bean 进行装配。后面会讲自动装配中的歧义性。

Java 依赖注入规范里面的@Inject@Autowired是同样的作用,大部分情况下可以互用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 148,827评论 1 317
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 63,511评论 1 266
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 99,318评论 0 218
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,108评论 0 189
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,112评论 1 266
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,387评论 1 185
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,905评论 2 283
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,657评论 0 177
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,144评论 0 223
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,744评论 2 225
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,100评论 1 236
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,565评论 2 222
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,041评论 3 216
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,769评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,301评论 0 178
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,173评论 2 239
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,313评论 2 242

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,036评论 18 139
  • 本章内容: 声明Bean 构造器注入和Setter方法注入 装配Bean 控制bean的创建和销毁 任何一个成功的...
    谢随安阅读 1,559评论 0 9
  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 6,618评论 2 22
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,147评论 6 345
  • 灯半昏时 月半明时 你入梦时 ————文/晚安
    数__风流人物阅读 360评论 0 4