Lion X

** Bean的配置** <Excerpt in index | 首页摘要>
Spring中bean的配置

<The rest of contents | 余下全文>

Spring装配bean

Spring配置的可选方案

当描述bean如何装配时,Spring具有非常大的灵活性,它提供了三种主要的装配机制:

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

建议:尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显示配置bean的时候,推荐使用类型安全并且比XML更加强大的JavaConfig。只有想使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时才应该使用XML。

自动化装配bean

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

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

创建一个可被发现的bean

  • CompactDisc接口

    1
    2
    3
    4
    5
    package soundsystem;

    public interface CompactDisc{
    void play();
    }
  • 带有@Component注解的CompactDisc实现类SgtPeppers

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package soundsystem;
    import org.springframework.stereotype.Component;

    @Component //声明组建类,并告诉spring要为这个类创建bean
    public class SgtPeppers implements CompactDisc{
    private String title = "sgt";
    private String artist = "The Beatles";

    public void play(){
    System.out.println("Playing " + title + " by " + artist);
    }
    }
  • @ComponentScan注解启用组建扫描

    1
    2
    3
    4
    5
    6
    7
    8
    package soundsystem;
    import org.springframework.context.annotation.componentScan;
    import org.springframework.context.annotation.Configuration;

    @Configuration
    @ComponentScan
    public class CDPlayerConfig{
    }
  • 通过XML启用组建扫描

    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="soundsystem"/>
    </beans>

为组件扫描的bean命名

  • @Component注解

    1
    2
    3
    4
    @Component("lonelyHeartsClub")
    public class SgtPeppers implements CompactDisc{
    ...
    }
  • @Named(Java依赖注入规范)

    1
    2
    3
    4
    5
    6
    7
    package soundsystem;
    import javax.inject.Named;

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

设置组建扫描的基础包

  • 指定不同的基础包

    1
    2
    3
    @Configuration
    @ComponentScan(basePackages={"soundsystem"})
    public class CDPlayerConfig{}
  • 设置多个基础包

    1
    2
    3
    @Configuration
    @ComponentScan(basePackages={"soundsystem", "video"})
    public class CDPlayerConfig{}
  • 指定为包中所包含的接口或类

    1
    2
    3
    @Configuration
    @ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class})
    public class CDPlayerConfig{}

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
*通过自动装配,将一个CompactDisc注入到CDPlayer之中
*/
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;
}

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

@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上

1
2
3
4
@Autowired
public void setCompactDisc(CompactDisc cd){
this.cd = cd;
}

@Autowired注解可以用在类的任何方法上

不管是构造器、Setter方法还是其他的方法,Spring都会尝试满足方法参数上所声明的依赖。假如有且只有一个bean匹配依赖的话,那么这个bean将会被装配进来。如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的required属性设置为false:

1
2
3
4
@Autowired(required=false)
public CDPlayer(CompactDisc cd){
this.cd = cd;
}

将required属性设置为false时,Spring会尝试执行自动装配,但是如果没有匹配成功的话,Spring将会让这个bean处于未装配状态。如果有多个bean都满足以来关系的话,Spring将会抛出一个异常,表明没有明确指定要选择哪个bean进行自动装配。

也可以使用@Inject实现自动装配

1
2
3
4
5
6
7
8
9
10
11
12
13
package soundsystem;
import javax.inject.Inject;
import javax.inject.Named;

@Named
public class CDPlayer{
...
@Inject
public CDPlayer(CompactDisc cd){
this.cd = cd;
}
...
}

 Comments