凡是过往,皆为序章

0%

Spring_03(基于注解的DI)

基于上篇总结的第一种基于XML的DI,本篇总结DI的第二种,也是更为常见和应用更为广泛的基于注解的DI。


基于注解的DI

对于使用注解的 DI 操作,将不再需要在 spring 配置文件中声明bean实例。spring中使用注解,需要在原有spring运行环境基础上再做一些改变。

需要在spring配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

使用注解的步骤:
1.加入maven的依赖spring-context ,在你加入spring-context的同时,间接加入spring-aop的依赖。使用注解必须使用spring-aop依赖

2.在类中加入spring的注解(多个不同功能的注解)

3.在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置

学习的注解:

  1. @Component

  2. @Repository

  3. @Service

  4. @Controller

  5. @Value

  6. @Autowired

  7. @Resource

定义Bean的注解 @Component

需要在类上使用注解 @Component,该注解的value属性用于指定该bean 的id值。

Student类文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.thorine.ba01;

import org.springframework.stereotype.Component;


/*
* @component:创建对象,等同于<bean></bean>
* 属性: value 就是对象的名称,也就是bean的id值,值是唯一的,创建的对象整个spring容器只有一个
* 位置:在类的上面
*
* spring中和@component功能一致,创建对象的注解还有:

1.@Repository (用在持久层类的上面):放在dao的实现类上面,
表示创建dao对象,dao对象是能访问数据库的。
2.@Service(用在业务层类的上面):放在service的实现类上面,
创建service对象,service对象是做业务处理,可以有事务等功能的。
3.@Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的
控制器对象,能够接受用户提交的参数,显示请求的处理结果。

以上三个注解的使用语法和@Component一样的。都能创建对象,但是这三个注解还有额外的功能。
@Repository , @Service , @controller是给项目的对象分层的。

只要不创建属于以上三个的种类的类对象,就使用 @Component
* */

// @Component(value = "myStudent") 正规用法
// @Component("myStudent") 省略 value 用法
@Component // 则会创建由 spring 默认指定名称的对象,即 student
public class Student {
private String name;
private Integer age;

public Student() {
System.out.println("Student 无参构造方法执行...");
}

public void setName(String name) {
this.name = name;
}

public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--
声明组件扫描器(component-scan),组件就是java对象
base-package:指定注解在你的项目中的包名
component-scan工作方式: spring会扫描逼历base-package指定的包,
把 包中和子包中 的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值。
-->

<context:component-scan base-package="com.thorine.ba01" />

<!-- 指定多个包的三种方式 -->
<!--第一种:使用多次组件扫描器,每个指定一个包-->
<context:component-scan base-package="com.thorine.ba01" />
<context:component-scan base-package="com.thorine.ba02" />

<!--第二种: 使用分隔符(; 或 ,) 分隔多个包名-->
<context:component-scan base-package="com.thorine.ba01;com.thorine.ba02" />

<!--第三种:指定父包-->
<context:component-scan base-package="com.thorine" />

</beans>

简单类型属性注入@Value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.thorine.ba02;

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

@Component("myStudent")
public class Student {
/*
* @Value:简单类型的属性赋值
* 属性:value 是 String 类型的,表示简单类型的属性值
* 位置:
* 1、在属性定义的上面,无需set方法,推荐使用。
* 2、在set方法上
* */

@Value("张飞")
private String name;
@Value("29")
private Integer age;

public Student() {
System.out.println("Student 无参构造...");
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

自动注入@Autowired

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.thorine.ba03;

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

@Component("myStudent")
public class Student {
/*
* @Value:简单类型的属性赋值
* 属性:value 是 String 类型的,表示简单类型的属性值
* 位置:
* 1、在属性定义的上面,无需set方法,推荐使用。
* 2、在set方法上
* */

@Value("张飞")
private String name;
@Value("29")
private Integer age;

/**
* 引用类型
* @Autowired: 实现引用类型的赋值,是自动注入的原理,支持byName,byType
* 默认使用byType自动注入
* 位置:属性定义的上面,无需使用set方法
*
* 属性:required,是一个Boolean类型,默认为 true,表示若引用类型赋值失败,则报错并中止程序运行
* 若是false,则程序正常执行,引用类型赋值为 null
*
* 如果要使用byName方式,则在属性上面加 @Autowired@Qualified(value="bean的id"): 表示使用指定名称的bean赋值
*/
@Autowired(required = false) // required属性推荐使用默认,即 true
// @Qualifier("mySchool") 打开注释则代表byName
private School school;

public Student() {
System.out.println("Student 无参构造...");
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}

JDK注解@Resource 自动注入

spring提供了对jdk中@Resource注解的支持。@Resource注解既可以按名称匹配Bean,也可以按类型匹配Bean,默认是按名称注入。@Resource可在属性上,可在set方法上。

1
2
3
4
5
6
7
/**
* @Resource: 来自jdk的注解,spring对其提供了支持,也是自动注入的原理,默认byName
*/

//@Resource 默认byName,如果byName找不到,byType
@Resource(name = "school") // 只使用byName
private School school;

注解与XML的对比

需要经常改变值用xml,不需要或不经常改变值的用注解。

注解更直观方便,查看类代码就能知道该类对象的信息。

~感谢你请我吃糖果~
-------------本文结束,感谢您的阅读,欢迎评论留言!-------------