您的运行环境禁止了 JavaScript 的实行,请开启后重新打开该页面! 新萄京娱乐网址2492777-[澳门官网]
精彩文章免费看

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那样清楚的表明它是做什么的



XML 地图 | Sitemap 地图