spring 装配bean

spring配置的可选方案

Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。作为开发人员需要告诉spring需要装配哪些bean并且如何将其装配到一起。spring提供了三种主要的装配机制

  • 在xml中进行显示的装配
  • 在Java中进行配置
  • 隐形的bean发现机制和自动配置

提供3种配置方案并不会使spring变得复杂。每种配置技术所提供的功能会出现一些重叠,所以在特定的场景中,确定哪种技术最为合适就会变得有些困难,但是不必紧张——在很多场景下,选择那种方案很大程度上只是个人的喜好问题,你尽可能选择自己喜欢的方式。并没有唯一的答案,你所做出的选择必须要适合你和你的项目。而且,我们也不是只能选择一种配置方案,spring的配置风格可以事互相搭配的,所以可以选择使用xml装配一些bean,使用spring基于Java的配置(JavaConfig)来装配另外一些bean,而将剩下的bean让spring去自动发现。

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

自动化装配bean

如果spring能够进行自动化装配的话,那又何苦还要显示地将这些bean装配到一起?

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

  • 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean
  • 自动装配(autowiring):spring自动满足bean之间的依赖

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

通过CD播放器的例子来说明自动化装配

maven pom.xml 依赖

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.11.RELEASE</version>
    </dependency>
    
    <!--spring test包  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.11.RELEASE</version>
        <scope>provided</scope>
    </dependency>

  </dependencies>

CompactDisc接口 【CD】

package soundsystem;

public interface CompactDisc {
    void play();
}

CompactDisc实现类SgtPeppers

package soundsystem;

import org.springframework.stereotype.Component;

@Component
public class SgtPeppers implements CompactDisc {
    private String title="远走高飞";
    private String artist="金志文";          //artist 中文为艺术家 画家的意思

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

**java配置类CDPlayerConfig **

package soundsystem;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {
    
}

**测试类CDPlayerTest **

package soundsystem;

import static org.junit.Assert.*;

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)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest {
    
    @Autowired
    private CompactDisc cd;
    
    @Test
    public void cdShouldNotBeNull(){
        assertNotNull(cd);
    }
}


划重点

@Component这个简单的注解表明该类会作为组件类,并告知spring要为这个类创建bean。
在程序中没有必要显式配置SgtPeppers bean,因为这个类使用了@Component注解,所以spring会为你把事情处理妥当不过,组件扫描默认是不启用的。我们还需要显示配置一下spring,从而命令它去寻找带有@Component注解的类,并为其创建bean

类CDPlayerConfig通过java代码定义了spring的装配规则,类中并没有显式地声明任何bean,只不过它使用了@ComponentScan注解,这个注解能够在spring中启用组件扫描,如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包,如果你更倾向于通过xml启用组件扫描的话,可以使用Spring context命名空间的<context:component-scan>元素。在xml中的beans标签中添加<context:component-scan base-package="soundsystem">

CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。注解@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。


为组件扫描的bean命名

Spring应用上下文中所有的bean都会给定一个ID,在前面的例子当中,尽管我们并没有明确的给SgtPeppers bean设置ID,但Spring会根据类名为其指定一个ID。具体来讲,这个bean所给定的ID为sgtPeppers,也就是将类名的第一个字母变为小写。
如果想为这个bean设置不同的ID,你所需要做的就是将期望的ID作为值传递给@Component注解。比如说,如果想将这个bean标识为loneyHeartsClub,那么你需要将SgtPeppers类的@Component注解配置为如下所示:

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

还有另外一种为bean命名的方式,这种方式不使用@Component注解,而是使用java依赖注入规范(Java Dependency Injection)中所提供的@Named注解来为bean设置ID:

package soundsystem;

import javax.injection.Named;

@Named("loneyHeartsClub")
public class SgtPeppers implements CompactDisc{
    ...
}

Spring 支持将@Named作为@Component注解的替代方案。两者之间有一些细微的差异,但是大多数场景中,他们是可以相互替代的。

不过我觉得就名字上而言,对于@Named并没有像@Component那样清楚的表明它是做什么的


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,010评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,974评论 6 342
  • 本章内容: 声明Bean 构造器注入和Setter方法注入 装配Bean 控制bean的创建和销毁 任何一个成功的...
    谢随安阅读 1,665评论 0 9
  • Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,我们需要做的就是告诉Spring要...
    xdoyf阅读 513评论 0 1
  • 这里说的Bean可不是豆子哦,是组件的意思,也就是哪些具有不同功能的类。将不同功能拆分成不同的组建,不仅能降低程序...
    郭之源阅读 2,771评论 0 0