Spring bean的装配-自动化装配

402 阅读3分钟

Spring的bean装配方案

Spring容器负责创建应用程序中的bean,并通过 DI(依赖注入) 来协调这些对象之间的关系。但是作为开发人员,需要告诉Spring要创建哪些bean并且如何将其装配到一起。

在Spring中有三种装配bean的方式:

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

自动化装配bean

在几种装配方式中,按照便利性来看,当属自动化装配最省事。那我们怎样才能实现自动装配呢?Spring从两个角度来实现自动化装配:

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

为了方便阐述组件扫描和自动装配,我们需要创建几个bean,代表音响系统的几个组件。理一下思路,首先创建一个CD唱片接口,以及CD唱片的一个具体实现类CDImpl,Spring会通过组件扫描发现CDImpl类并创建为一个bean。再创建一个Player播放器接口,以及它的实现类CDPlayer类(CD播放器),Spring也会通过组件扫描发现CDPlayer类,并将CD bean注入到CDPlayer中。

以下是代码示例:

CD接口

package com.abiao._02_Autowiring;

/**
 * CD接口
 **/
public interface CD {
    /** 播放方法 */
    void play();
}

CDImpl(CD实现类)

package com.abiao._02_Autowiring;

import org.springframework.stereotype.Component;

/**
 * CD接口的实现类
 **/
@Component("cd1")
public class CDImpl implements CD {
    public void play() {
        System.out.println("CD111在播放。。。");
    }
}

CDImpl2(CD实现类2)

package com.abiao._02_Autowiring;

import org.springframework.stereotype.Component;

/**
 * CD接口的实现类
 **/
@Component("cd2")
public class CDImpl2 implements CD {
    public void play() {
        System.out.println("CD222在播放。。。");
    }
}

Player(播放器接口)

package com.abiao._02_Autowiring;

/**
 * 播放器接口
 **/
public interface Player {

    void play();
}

CDPlayer(CD播放器类)

package com.abiao._02_Autowiring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * CD播放器
 **/
@Component
public class CDPlayer implements Player{

    private CD cd;
    
    /** 构造器注入 */
    @Autowired
    public CDPlayer(CD cd2){
        this.cd = cd2;
    }
    
    /** 播放器播放 */
    public void play() {
        cd.play();
    }
}

java配置类 开启组件扫描

package com.abiao._02_Autowiring;

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

@Configuration
@ComponentScan(basePackages = "com.abiao._02_Autowiring")
//@ComponentScan(basePackageClasses = CD.class)
public class CDPlayerConfig {
}

测试自动装配

import com.abiao._01_demo.CDPlayerConfig;
import com.abiao._02_Autowiring.CD;
import com.abiao._02_Autowiring.CDPlayer;
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;

/**
 * CD播放器测试 自动装配
 **/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {

    @Autowired
    private CD cd2;

    @Autowired
    private CDPlayer player;
    
    @Test
    public void play(){
        System.out.println(cd2);
        System.out.println(player);
        player.play();
    }
}

结果:

图片.png

自动装配的实现细节

从结果看我们已经成功的实现了自动装配,下面说明下实现细节:

组件扫描:

  • @Component :这个注解标记的类会作为组件类,并告知Spring要为这个类创建bean
    • 其中还可通过 @Component("bean的名称") 为bean命名,若未设置默认以当前类名首字母小写命名。
  • @ComponentScan(basePackages = "基础包名") :这个注解会开启组件扫描
    • 若不配置基础包名,则以当前配置类所在包作为基础包,扫描当前包及其子包中的组件类。也可配置基础包类,以该类所在包作为基础包。
    • 若不喜欢配置类方式,也可通过XML配置Spring context 命令空间的<context:component-scan base-package="基础包名" />方式启动组件扫描。

自动装配:

  • @Autowired :该注解会让Spring在应用上下文中寻找满足注入需求的bean进行装配注入。
    • 若以接口类型接受bean,他会找到它的实现类注入,如果有多个实现类他会以bean的名称进行匹配,若匹配不上并且没有设置required属性为false,则会抛出异常。
    • @Autowired 注入方式有很多种:构造器注入,set方法注入,还有实例字段注入,该注解可以用在类中任何方法上,只不过前三种最常用。

以上就是Spring中 bean的自动装配,也是我们开发中最常用的装配方式。

每天进步一点点,越慢才能越快!