Spring的三种装配Bean的方式

一.自动扫描+自动装配

简单bean,初始化不需要基本bean之外的其他参数,无参构造函数或者仅需要其他bean,如果需要其他bean作为属性需要用@Autowired注入,需要事先定义好装配策略。

关键词:
@Component:标识Bean,可被自动扫描发现
@Configuration+ @ComponentScan(basepackages=”main”) :
@Autowired:自动装配,查找容器中满足条件的Bean,注入。

public interface MediaPlayer {
  String play();
}
@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

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

public interface CompactDisc {
  String play();
}


@Component
public class SgtPeppers implements CompactDisc {
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artist = "The Beatles";

        public String play () {
            System.out.print("abc");
            return "SgtPeppers";
        }
    }

//配置类:
@Configuration
@ComponentScan
public class CDPlayerConfig { 
}

二. 通过java代码装配bean

适用情况:所有情况基本适用,区别方法一:不需要事先定义好装配策略,因为会在config.java中定义。

关键词:
@Configuration + @Bean:创建config.java,并定义bean的获取方法且需要用
@Bean注解,需要注入其他Bean作为参数不需要使用@Autowired。
@Autowired:自动装配,查找容器中的Bean,注入。

public interface MediaPlayer {
  void play();
}

public class CDPlayer implements MediaPlayer {
  private CompactDisc cd;
  @Autowired
  public CDPlayer(CompactDisc cd) {
    this.cd = cd;
  }
  public void play() {
    cd.play();
  }
}

public interface CompactDisc {
  void play();
}
public class SgtPeppers implements CompactDisc {
  private String title = "Sgt. Pepper's Lonely Hearts Club Band";  
  private String artist = "The Beatles";
  public void play() {
    System.out.println("Playing " + title + " by " + artist);
  }
}

// 此处没有@ComponentScan 注解, 
@Configuration
public class CDPlayerConfig {

  @Bean
  public CompactDisc compactDisc() {
    return new SgtPeppers();
  }

  @Bean
  public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
  }

}

三. 使用xml配置

使用情况:大部分情况。
关键词:及其子元素。

基础类:

public interface MediaPlayer {
  void play();
}

public class CDPlayer implements MediaPlayer {
  private CompactDisc cd;
  @Autowired
  public CDPlayer(CompactDisc cd) {
    this.cd = cd;
  }
  public void play() {
    cd.play();
  }
}

public interface CompactDisc {
  void play();
}
public class SgtPeppers implements CompactDisc {
  private String title = "Sgt. Pepper's Lonely Hearts Club Band";  
  private String artist = "The Beatles";
  public void play() {
    System.out.println("Playing " + title + " by " + artist);
  }
}

xml

<?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:c="http://www.springframework.org/schema/c"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="compactDisc" class="soundsystem.BlankDisc"
        c:_0="Sgt. Pepper's Lonely Hearts Club Band" 
        c:_1="The Beatles" />

  <bean id="cdPlayer" class="soundsystem.CDPlayer"
        c:_-ref="compactDisc" />

</beans>

混合装配
Spring的配置风格是可以互相搭配的,所以你可以选择使用XML装配一些bean,使用Spring基于Java的配置(JavaConfig)来装配另一些bean,而将剩余的bean让Spring去自动发现。

//此处创建一个全局的bean装配配置文件
@Configuration
@Import(CDPlayerConfig.class)  //导入java装配
@ImportResource("classpath:cd-config.xml")  //导入xml装配
public class SoundSystemConfig {

}

关于混合配置,第一件需要了解的事情就是在自动装配时,它并不在意要装配的bean来自哪里。自动装配的时候会考虑到Spring容器中所有的bean,不管它是在JavaConfig或XML中声明的还是通过组件扫描获取到的,

我同时建议尽可能使用自动化配置,以避免显式配置所带来的维护成本。但是,如果你确实需要显式配置Spring的话,应该优先选择基于Java的配置,它比基于XML的配置更加强大、类型安全并且易于重构。


备注:@
ComponentScan
这个注解能够在Spring中启用组件扫描,@ComponentScan默认会以配置类所在包为基础包进行扫描组件

配置扫描多个基础包

//直接设置包的名称(string)
//@ComponentScan(basePackages = {"autoconfigBeans","controller"})

//这些类所在的包将作为组件扫描的基础包
@ComponentScan(basePackageClasses = {CDPlayer.class, LoginCommand.class})