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 注解的类。有两种方式开启组件扫描。

在配置类(@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 {

}

在 Spring 的 XML 配置文件中使用 元素,开启组件扫描。这需要引入 Spring 的 context 命名空间。代码如下:

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">

自动装配

简单来说,自动装配就是让 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 进行自动装配。

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: