SpringIoC — 基于注解的DI(总结)
Posted 王六六的IT日常
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringIoC — 基于注解的DI(总结)相关的知识,希望对你有一定的参考价值。
基于注解的DI
使用spring提供的注解,完成java对象创建,属性赋值。
先总结:
1.创建对象的注解
@Component : 普通java对象
@Respository: dao对象,持久层对象, 表示对象能访问数据库。
@Service :service对象, 业务层对象, 处理业务逻辑,具有事务能力
@Controller:控制器对象, 接收请求,显示请求的处理结果。 视图层对象
2.简单类型属性赋值的注解
@Value
3.引用类型赋值的注解
@Autowired: spring提供的注解 . 支持byName, byType
- @Autowired: 默认就是byType
- @Autowired 与 @Qualifer(value=“bean的id”) : 使用byName
@Resource : 来自jdk中的注解,给引用类型赋值的,默认是byName
- @Resource: 先使用byName, 在byType
- @Resource(name=“bean的id”) :只使用byName注入
一、创建对象的注解
1.@Component
定义 Bean 的注解(掌握)
创建java对象,相当于bean标签的作用
举例创建moudle-maven-ch04-di-anno
在pom.xml中加入spring依赖
<!--Spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
使用注解必须有aop依赖
加入spring-context则spring-aop自动加入;
aop也可以单独加入
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
1) 创建Student类:Student.java
/**
* @author WanZi
* @create 2021-11-05
*/
public class Student {
private String name;
private Integer age;
public Student() {
System.out.println("Student的无参构造方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\\'' +
", age=" + age +
'}';
}
}
2) 使用注解创建student对象:
使用value 指定对象的名称
@Component
: 表示创建对象,对象放到容器中。 作用是<bean>
- 属性:value ,表示对象名称,也就是bean的id属性值
- 位置:在类的上面,表示创建此类的对象。
@Component(value = "myStudent")
等同于
<bean id="myStudent" class="com.bjpowernode.ba01.Student" />
3) 创建spring配置文件applicationContext.xml
base-package 👇
4) 测试
大致流程:
总结:
注解使用的核心步骤:
1.在源代码加入注解,例如@Component
2.在spring的配置文件,加入组件扫描器的标签
<context:component-scan base-package="注解所在的包名"/>
三种@Component
的使用形式:
1.使用value 指定对象的名称 @Component(value = "myStudent")
2.省略value @Component("myStudent2")
------使用最多
3.没有提供自定义对象名称 @Component
,使用框架的默认对象名称:类名首字母小写
其他创建对象的注解
和@Component
功能相同的创建对象的注解。
- @Repository : 放在dao接口的实现类上面,表示创建dao对象,持久层对象,能访问数据库
- @Service : 放在业务层接口的实现类上面, 表示创建业务层对象, 业务层对象有事务的功能
- @Controller:放在控制器类的上面,表示创建控制器对象。 属于表示层对象。控制器对象能接受请求,把请求的处理结果显示给用户。
以上四个注解都能创建对象.
但是@Repository @Service @Controller
有角色说明, 表示对象是分层的。对象是属于不同层的,具有额外的功能。
声明组件扫描器
使用注解必须加入👇
- component-scan:翻译过来是组件扫描器,组件是java对象。
- 属性: base-package 注解在你的项目中的包名。框架会扫描这个包和子包中的所有类,找类中的所有注解。遇到注解后,按照注解表示的功能,去创建对象, 给属性赋值。
扫描多个包的三种方式,不可重复扫描
<!--第一种,使用多次组件扫描器-->
<context:component-scan base-package="com.bjpowernode.bao1"/>
<context:component-scan base-package="com.bjpowernode.bao2"/>
<!--第二种,使用分隔符( ;或,),指定多个包-->
<context:component-scan base-package="com.bjpowernode.bao1;
com.bjpowernode.bao2"/>
<!--第三种:指定父包-->
<context:component-scan base-package="com.bjpowernode" />
二、属性赋值的注解
1. @Value
----- 简单类型属性赋值(掌握)
简单类型属性赋值:@Value(value=" ") / @Value(" ")
- 属性:value 简单类型属性值
- 位置:
1)在属性定义的上面 ,无需set方法,推荐使用
2)在set方法的上面
举例:
在属性定义的上面 ,无需set方法,推荐使用
赋值后测试结果如下:
在set方法的上面
属性值从外部文件获得
在resources文件夹下创建一个属性文件xxx.properties
想让spring使用该属性文件,得让spring读到该文件,则在spring配置文件中进行设置:
<!--读取外部的属性配置文件
property-placeholder:读取properties这样的文件
-->
<context:property-placeholder location="classpath:/myconf.properties" />
在Student.java
中:
使用外部属性文件中的数据,语法 @Value(${"key"})
只需在外部属性文件中修改属性值即可.
三、引用类型赋值的注解
1. @Autowired
(掌握) — byType
@Autowired: spring框架提供的,给引用类型赋值的,使用自动注入原理。
支持byName,byType。默认是byType.
位置:
1)在属性定义的上面,无需set方法,推荐使用
2)在set方法的上面
举例:
按照byType原则,需要在容器中拿出一个跟school同源关系的对象赋给school属性。
👇
在spring配置文件中进行声明
👇
school中必须有set方法—才能进行属性文件对引用类型赋值
使用属性配置文件进行引用类型赋值:
使用注解进行引用类型赋值
在School.java中:
1.进行School类型的myschool对象创建 @Component
2.使用@Value(value=" ") / @Value(" ")
进行属性赋值
👇
2. @Autowired
与@Qualifier
(掌握)----byName 自动注入
byName
自动注入:
1)@Autowired:给引用类型赋值
2)@Qualifer(value="bean的id")
:从容器中找到指定名称的对象,把这个对象赋值给引用类型。
3. @Autowired
注解的 required
属性
@Autowired: spring框架提供的,给引用类型赋值的,使用自动注入原理。
支持byName,byType。默认是byType.
属性:
- required :boolean类型的属性,默认true
- true:spring在启动的时候,创建容器对象时候会检查引用类型是否赋值成功。如果赋值失败, 终止程序执行,并报错。
- false:引用类型赋值失败,程序正常执行,不报错。引用类型的值是null
1) @Autowired(required=true(省略))
默认true (推荐)
把错误情况尽早暴露出来,进行解决
引用类型对象不一致时👇赋值不成功
报错:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type ‘com.bjpowernode.bao5.School’ available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myschool111111)}
2) @Autowired(required=false)
设置为false时
把错误情况延后到使用时
4. JDK 注解@Resource
自动注入(掌握)
Spring 提供了对 jdk 中@Resource
注解的支持。
@Resource
: 来自jdk中,给引用类型赋值的,支持byName,byType
.默认是byName
位置:
- 在属性定义的上面,无需set方法, 推荐使用
- 在set方法的上面
1)@Resource
先使用byName赋值,如果赋值失败,再使用byType.
举例:
为啥呢?👇
因为@Resource
先使用byName赋值,如果赋值失败,再使用byType.
本例是byType
赋值成功。
说明:
使用jdk1.8带有@Resource注解, 高于jdk1.8没有这个@Resource,需要加入一个依赖。
依赖寻找途径:链接:maven仓库----搜索annotation
👇
👇加入到pom.xml文件的<dependencies> </dependencies>
中
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
👇查看本地仓库
给school对象赋值:
2) @Resource
只使用byName
注入(赋值)
@Resource只使用byName赋值:使用注解属性name=“bean的id”
即@Resource(name="bean的id")
举例:
以上是关于SpringIoC — 基于注解的DI(总结)的主要内容,如果未能解决你的问题,请参考以下文章