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(总结)的主要内容,如果未能解决你的问题,请参考以下文章

Spring学习总结五——SpringIOC容器五

Spring使用大全

spring security学习总结

巨人的肩膀JAVA面试总结

Spring IoC基于XML的DI详细配置全解两万字

Spring总结四:IOC和DI 注解方式