前面我们介绍Spring IoC装载的时候,使用XML配置这种方法来装配Bean,这种方法可以很直观的看到每个Bean的依赖,但缺点也很明显:写起来非常繁琐,每增加一个组件,就必须把新的Bean配置到XML中。

有没有更简单的配置方式呢?

有,Spring为我们提供一种可以不依赖XML配置,自动扫描并装配Bean的方法,基于注解的自动挡装配方式。

Spring 通过注解实现自动装配的步骤:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

1、引入依赖

使用注解的第一步,就是要在项目中引入以下 Jar 包:
org.springframework.core-5.3.13.jar
org.springframework.beans-5.3.13.jar
spring-context-5.3.13.jar
spring-expression-5.3.13.jar
commons.logging-1.2.jar
spring-aop-5.3.13.jar
注意,除了 spring 的四个基础 jar 包和 commons-logging-xxx.jar 外,想要使用注解实现 Spring 自动装配,还需要引入Spring 提供的 spring-aop 的 Jar 包。

2、开启组件扫描

Spring 默认不使用注解装配 Bean,因此需要开启Spring Bean的自动扫描功能,有三种方式:

2.1  XML配置

通过 <context:component-scan> 元素开启 Spring Beans的自动扫描功能。开启此功能后,Spring 会自动从扫描指定的包(base-package 属性设置)及其子包下的所有类,如果类上使用了 @Component 注解,就将该类装配到容器中。

<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描功能-->
<context:component-scan base-package="net.biancheng.c"></context:component-scan>
</beans>

2.2  通过Java配置方式,启动自动扫描功能

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.cn.config")
public class BlogSystemConfig {
/**
* 在这里实现java方式的配置,
*/
}

2.3  SpringBoot中可以利用@SpringBootApplication注解的方式启动自动扫描功能  

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

3、使用注解定义Bean 

Spring 提供以下多个注解,这些注解可以直接标注在Java类上,将它们定义成Spring Bean。

@Component:用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。使用时只需将该注解标注在相应类上即可。

@Repository: 用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Service:通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Controller:通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

4、依赖注入

我们可以通过以下注解将定义好 Bean 装配到其它的 Bean 中。

@Autowired

可以应用到 Bean 的属性变量、setter 方法、非 setter 方法及构造函数等,默认按照 Bean 的类型进行装配。

@Autowired 注解默认按照 Bean 的类型进行装配,默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合 @Qualifier 注解一起使用

@Resource

作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 的名称进行装配。

@Resource 中有两个重要属性:name 和 type。
Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。

  • 如果指定 name 属性,则按实例名称进行装配;
  • 如果指定 type 属性,则按 Bean 类型进行装配;
  • 如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。

@Qualifier

与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。

5、案例

下面以一个例子说明:

1、创建接口CompactDisc

package soundsystem;

public interface CompactDisc {
void play();
}

 2、创建带有 @Component 注解的 CompactDisc 实现类 SgtPeppers

package soundsystem;

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"; public void play() {
System.out.println("Playing " + title + " by " + artist);
} }

 3、启用组件扫描

package soundsystem;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan
public class CDPlayerConfig {
}

 或者配置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:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="soundsystem" /> </beans>

 4、测试

package soundsystem;

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
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; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest { @Autowired
private CompactDisc cd; @Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
} }

 

参考文献:

http://c.biancheng.net/spring/autowire-annotation.html

https://codeantenna.com/a/q59QIGKYJu

https://potoyang.gitbook.io/spring-in-action-v4/di-2-zhang-zhuang-pei-bean/untitled/2.2.1-chuang-jian-ke-bei-fa-xian-de-bean   《Spring实战(第四版本)》

最新文章

  1. 在docker容器中vi指令找不到
  2. CSS属性小结之--半透明处理
  3. 161227、js显示对象所有属性和方法的函数
  4. 『TCP/IP详解——卷一:协议』读书笔记——15
  5. entityframework lamda 使用where时的注意事项
  6. java 22 - 6 多线程之线程调度和设置线程的优先级
  7. POJ 1990 MooFest --树状数组
  8. 怎样写 OpenStack Neutron 的 Extension (四)
  9. 如何用linux远程登录windows计算机
  10. PLSQL_PLSQL中DML/DDL/DCL的概念和区分(概念)
  11. LR实现http协议性能测试脚本
  12. Android Every day a new function:one
  13. Android项目实战手机安全卫士(01)
  14. Logistic Regression理论总结
  15. asp.net mvc 通过StyleBundle添加样式后,没有作用
  16. Key in_hidden/batch_normalization/beta not found in checkpoint
  17. 缺陷管理工具Jira安装参考
  18. Matlab_audiowrite_音频生成
  19. 使用Spring Boot开发 “Hello World” Web应用
  20. ubuntu 下抓包

热门文章

  1. LGP5437题解
  2. ArcMap操作随记(14)
  3. java 知识点梳理
  4. 74CMS 3.0 存储型XSS漏洞
  5. swing 实现用户登录注册界面(不使用数据库)
  6. markdown类型文件编辑大全
  7. 修复ST-LINK V2下载器 | ST-LINK V2下载器烧录DAPLink固件
  8. CF1481X Codeforces Round #699
  9. http多路复用?
  10. SpringAOP--代理