Spring 自动化装配 Bean

本文详细介绍了Spring框架中的自动化装配和组件扫描机制,包括@Component注解的使用、自动装配(@Autowired)的原理,以及如何通过配置开启组件扫描,避免依赖关系问题和异常处理。
摘要由CSDN通过智能技术生成

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

  • 组件扫描:Spring 会自动发现应用上下文中所创建的 bean。
  • 自动装配:Spring 会自动满足 bean 之间的依赖关系。

组件

Spring 中使用 @Component 注解将一个类标注为组件类,并告知 Spring 要为这个类创建 bean,这样就不用显式配置了。代码如下:
首先,我们创建一个 CompactDisc 接口

package org.example.autoconfig;

public interface CompactDisc {
	void play();
}

然后,创建一个 CompactDisc 接口的实现类 SgtPeppers,并使用 @Component 注解将该类标注为一个组件类。

package org.example.autoconfig;

import org.springframework.stereotype.Component;

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

Spring 应用上下文会为所有的 bean 创建一个 ID,默认值就是类名的首字母小写。如果想要为 bean 设置 ID 值,只需要在 @Component 注解中传入 ID 的值即可。例如:

package org.example.autoconfig;

import org.springframework.stereotype.Component;

// 设置 SgtPeppers 类的 bean 的 ID 为 lonelyHeartsClub
@Component("lonelyHeartsClub") 
public class SgtPeppers implements CompactDisc {
    ...
}

组件扫描

Spring 的组件扫描默认是不开启的,需要显式地配置,从而 命令 Spring 去寻找带有 @Component 注解的类。有两种方式开启组件扫描。

  1. 在配置类(@Configuration 注解标注的类)中使用 @ComponentScan 注解,开启组件扫描。
    @ComponentScan 默认会扫描与配置类相同的包以及这个包下的所有子包,带有 @Component 注解的类,并自动为其创建一个 bean。代码如下:
package org.example.autoconfig;

@Configuration
@ComponentScan
public class CDPlayerConfig {
	...
}

如果想扫描指定的包,可以在 @ComponentScan 注解的 value 属性中,使用 String 类型的值指明包名称:

package org.example.autoconfig;

@Configuration
@ComponentScan("org.example.autoconfig")
public class CDPlayerConfig {
	...
}

如果想要更加清晰地表明设置的是基础包,可以通过 basePackages 属性进行设置,可以设置一个或者多个基础包:

package org.example.autoconfig;

@Configuration
// 设置一个基础包
@ComponentScan(basePackages = "org.example.autoconfig")
// 设置多个基础包
// @ComponentScan(basePackages = {"org.example.autoconfig", "org.example.xmlconfig"})
public class CDPlayerConfig {
}

除了使用字符串设置包名称外,还可以将 basePackageClasses 属性设置为包中所包含的类或者接口,这些类所在的包将会作为组件扫描的基础包。

@Configuration
@ComponentScan(basePackageClasses = { CompactDisc.class, SgtPeppers.class})
public class CDPlayerConfig {
}
  1. 在 Spring 的 XML 配置文件中使用 <context:component-scan> 元素,开启组件扫描。这需要引入 Spring 的 context 命名空间。代码如下:
<?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://http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">
       
	<!-- 开启组件扫描, 并指定扫描的基础包为 soundsystem -->
    <context:component-scan base-package="soundsystem"/>
</beans>

自动装配

简单来说,自动装配就是让 Spring 自动满足 bean 依赖的一种方法,在满足依赖的过程中,会在 Spring 应用上下文中寻找匹配某个 bean 需求的其他 bean。为了声明要进行自动装配,可以使用 Spring 的 @Autowired 注解。
首先,先声明一个 MediaPlayer 接口,代码如下:

package org.example.javaconfig;

public interface MediaPlayer {
    void play();
}

然后,在它的实现类的构造函数上使用 @autowired 注解,当 Spring 创建 CDPlayer 类的 bean 的时候,会通过这个构造器来进行实例化并且传入一个 CompactDisc 类的 bean,实现自动装配,代码如下:

package org.example.javaconfig;

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

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;

    // 使用在构造函数上,当Spring要创建CDPlayer的bean时,会自动注入CompactDisc的bean
    @Autowired
    public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }
    @Override
    public void play() {
        cd.play();
    }
}

@Autowired 注解不仅能够用在构造器上,还能在属性的 Setter 方法上,如果 CDPlayer 类有一个 setCompactDisc() 方法,可以采用下面的注解形式进行自动装配:

@Autowired
public void setCompactDisc(CompactDisc cd){
	this.cd = cd;
}

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

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

将 required 属性设置为 false 时,Spring 会尝试执行自动装配,但是如果没有匹配的 bean 的话,Spring 将会让这个 bean 处于未装配状态。但是,把 required 属性设置为 false 时,需要谨慎对待。如果在代码中没有进行 null 检查的话,这个处于未装配状态的属性有可能会出现 NullPointerException。
如果有多个 bean 都能满足依赖的话,Spring 将会抛出一个异常,表明没有明确指定要选择哪个 bean 进行自动装配。

  • 35
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值