Spring - 关于模式注解和依赖注入的一些理解
目录
前言
模式注解(Stereotype Annotations)是一种用于声明在应用中扮演"组件"角色的注解。如 Spring Framework 中的 @Component, @Service, @Controller, @Repository 等。只要在相应的类上标注这些注解,就能成为 Spring 中组件(Bean)。
1、模式注解
1.1、常见的模式注解
Spring Framework 注解 | 场景说明 | 起始版本 |
---|---|---|
@Component | 通用组件模式注解 | 2.5 |
@Controller | 控制器模式注解 | 2.5 |
@Service | 服务模式注解 | 2.5 |
@Repository | 数据仓储模式注解 | 2.0 |
@Configuration | 配置类模式注解 | 3.0 |
不同的模式注解虽然功能相同,但因其代表含义的不同可以将将服务的清晰分层表示。
1.2、@Component
- @Component注解的作用是把一个组件/类/bean加入IOC容器并实例化。
@Component
public class Bannner {
}
1.3、@Service、@Controller、@Repository
- @Component最初spring框架设计的,后来为了标识不同代码层,衍生出@Controller,Service,Repository三个注解 作用相当于配置文件的bean标签,被注解的类,Spring始化时,就会创建该对象。
- @Controller,表示为 WEB 控制层 ,处理各种 HTTP 交互。
- @Service,表示为内部服务层 ,处理内部服务各种逻辑。
- @Repository,表示为数据控制层,代表数据库增删改查动作。
1.4、@Configuration
- @Configuration,用于定义配置类,替换xml配置文件,可以将注解的类内部多个被@Bean注解的方法构建Bean定义加入Spring容器。
2、Spring的注入方式
@Component,@Service,@Controller,@Repository标记类生成Bean,而Spring通过DI(依赖注入)实现IOC(控制反转)常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的属性注入。
2.1、属性注入
/**
* @Autowired 属性/字段注入
* @Autowired是自动注入,自动从spring的上下文找到合适的bean来注入
*/
@Autowired
public Bannner banner;
2.2、构造注入
/**
* 构造注入
* @param banner
*/
public BannerController(Bannner banner) {
this.banner = banner;
}
2.3、setter注入
/**
* setter注入
* @param banner
*/
@Autowired
public void setBanner(Bannner banner) {
this.banner = banner;
}
3、@Autowired 的注入方式
@Autowired注解是一个用于容器(container)配置的注解,与它同属容器配置的注解还有:@Required,@Primary, @Qualifier等等。Autowire意为自动装配,Spring自动装配提供一种加载机制 - 将Bean自动加载到IOC容器里,和我们需要使用Bean的类组装在一起使用。
3.1、@Autowired - 被动注入 - byType
@Autowired默认注入方式是按类型注入,根据类型查找Bean,查找结果为一个时直接注入,多个时报错,适用于只有一个Bean实现了接口的情况。
public class TestController {
@Autowired
private TestInter testInter;
@GetMapping(value = "/test")
public void test(){
testInter.sayHello();
}
}
public interface TestInter {
void sayHello();
}
@Component
public class TestOne implements TestInter {
@Override
public void sayHello() {
System.out.println("Hello TestOne");
}
}
- 此时接口访问结果为:
3.2、@Autowired - 被动注入 - byName
在按类型注入失败的情况下,会按字段的名字(byName)推断注入哪个Bean。
- 此时再加入一个TestInter的实现类来测试
@Component
public class TestTwo implements TestInter {
@Override
public void sayHello() {
System.out.println("Hello TestTwo");
}
}
- @Autowired根据类型查找Bean结果多个时报错。
- 将代码修改为byName按字段名字注入:
@Autowired
private TestInter testOne;
- 此时接口访问结果为:
3.3、@Autowired - 主动注入
当按类型与按字段名匹配没有找到确定的Bean,通过@Qualifier("") 指定注入的bean
@Autowired
@Qualifier("testTwo")
private TestInter testInter;
- 此时接口访问结果为:
![](https://img-blog.csdnimg.cn/d1b51b924c4d4ea88f8fecaa32708d63.jpg)