spring 装配bean

作者: JIN520 | 来源:发表于2017-10-03 01:01 被阅读0次

    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 装配bean

        本文链接:https://www.haomeiwen.com/subject/fgrxyxtx.html