JAVAEE一>Spring IoC和DI详解

news/2025/2/24 15:13:02

目录

  • Spring容器说明:
  • Ioc容器优势:
  • DI介绍:
  • 从Spring获取对象:
    • 获取对象的方法:
    • 关于上下文的概念:
  • @Controller注解(控制层:接收参数并响应):
  • @Service注解(业务逻辑层:处理业务数据):
  • @Repository注解(数据层:调用数据库用来获取数据):
  • @Configuration注解(配置层):
  • @Component注解在(组件层):
  • @Bean注解(方法注解):
  • 上面五大注解和方法注解的区别:
    • bean-->对象的命名规则:
  • Spring扫描路径:
  • 什么是DI:
    • DI的常用方法:
      • 1.属性注入:
      • 2.构造方法注入:
      • 3.set方法注入:
    • @Autowired存在的问题:
      • 解决措施:
        • 1.加上@Qualifier注解进一步通过名称来找bean:
        • 2.加上@Primary注解:
        • 3.加上@Resource注解:
  • 面试题:@Resource和@Autowired的区别:
    • @Autowired的装配顺序:

Spring容器说明:

Spring 就是⼀种IoC容器,Spring 容器 管理的主要是对象, 这些对象, 我们称之为"Bean". 我们把这些对象交由Spring管理, 由
Spring来负责对象的创建和销毁. 我们程序只需要告诉Spring, 哪些需要存, 以及如何从Spring中取出对象


把对象交给Spring管理,需要添加一些注解这里共有两类注解可以使用:
1.类注解:@Controller,@Service,@Repository,@Component,@Configuration


2.方法注解:@Bean


我们接下来就主要围绕注解的使用来讲解

Ioc容器优势:

1.控制权发生反转:不在需要使用方,创建对象并控制依赖,不需要自己创建对象和初始化,这就是控制反转


2.集中资源管理:
IOC容器会帮我们管理一些资源(对象)时, 只需要从IoC容器中去取
就可以了


3.降低资源的耦合度:我们在创建实例的时候不需要了解其中的细节, 降低了使用资源双方的依赖程度

DI介绍:

DI就是注入依赖,容器在运行时动态的为程序注入所需的依赖
依赖就是程序运行时需要的一些成员属性

从Spring获取对象:

因为对象被交给了Spring管理,所以我们要先获取Spring的上下文->ApplicationContext,再来根据方法获取对象

获取对象的方法:

这里我们主要根据名称获取,这个名称是唯一的,根据类型获取,这个类型就是某个类,根据名称+类型获取

java">// 1. 根据bean名称获取bean
 Object getBean(String var1) throws BeansException;
 // 2. 根据bean名称和类型获取bean
 <T> T getBean(String var1, Class<T> var2) throws BeansException;
 // 3. 按bean名称和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的bean
 Object getBean(String var1, Object... var2) throws BeansException;
 // 4. 根据类型获取bean
 <T> T getBean(Class<T> var1) throws BeansException;
 // 5. 按bean类型和构造函数参数动态创建bean, 只适⽤于具有原型(prototype)作⽤域的
bean
 <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

关于上下文的概念:

比如线程上下文:一个栈结构,用于存储上层线程的上下文信息,以便继续执行。
包含当前线程的位置、设置、本地变量等信息。类似于一个环境和这里的Spring容器的上下文, 就是指当前的运行环境, 也可以看作是⼀个容器, 容器里存了很多内容, 这些内容是当前
运行的环境
**

@Controller注解(控制层:接收参数并响应):

使用@Controller 存储对象(bean):

java">import org.springframework.stereotype.Controller;

@Controller
public class HelloController {
    public void print(){
        System.out.println("do Controller");
    }
}

用名称获取对象:就是把对象交给Spring容器管理

java">public static void main(String[] args) {
        //获取Spring上下文
       ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);

       HelloController bean1 = (HelloController) context.getBean("helloController");
       bean1.print();

这里是引用

用类型获取对象:

java"> HelloController bean2 = context.getBean(HelloController.class);
       bean2.print();



这里是引用

使用类型和名称获取对象:

java">HelloController bean3 = context.getBean("helloController",HelloController.class);
        bean3.print();

这里是引用

@Service注解(业务逻辑层:处理业务数据):

存储对象代码如下:

java">import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void print(){
        System.out.println("do Service");
    }
}

使用类型获取对象:

java"> UserService bean7 = context.getBean(UserService.class);
        bean7.print();

@Repository注解(数据层:调用数据库用来获取数据):

存储对象代码如下:

java">import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    public void print(){
        System.out.println("do Repository");
    }
}

使用类型获取对象:

java">UserRepository bean6 = context.getBean(UserRepository.class);
        bean6.print();

@Configuration注解(配置层):

存储对象代码如下:

java">import org.springframework.context.annotation.Configuration;

@Configuration("reNameBean")
public class UserConfig {

    public void print(){
        System.out.println("do config");
    }
}

使用类型获取对象:

java">UserConfig bean4 = context.getBean(UserConfig.class);
        bean4.print();

@Component注解在(组件层):

存储对象代码如下:

java">import org.springframework.stereotype.Component;

@Component
public class UserComponent {
    public void print(){
        System.out.println("do Component");
    }
}

使用类型获取对象:

java">UserComponent bean8 = context.getBean(UserComponent.class);
        bean8.print();

@Bean注解(方法注解):

注意:方法注解使用时候注意要搭配以上的五大类注解使用:


Bean这个注解使用的场景:一个类需要多个对象:(上面的五大注解,只可以有一个对象)


以上五大注解和这个类注解都可以修改,对象的名字,就是让Spring按照我们的名字管理
在这里插入图片描述

查看对象:按照修改的对象

java">Student bean9 = (Student) context.getBean("ss1");
        System.out.println(bean9);

        Student bean10 = (Student) context.getBean("s2");
        System.out.println(bean10);

上面五大注解和方法注解的区别:

除了控制层必须使用注解(@Controller)之外,其他四个注解都可以替换使用,但是一般规范来说都在各自的层级使用


控制层使用其他注解有时候可以使用成功但是不稳定不规范


注解细节:
在这里插入图片描述

bean–>对象的命名规则:

从Spring容器获取对象时,通过名称获取就需要命名:


五大类注解:
以小驼峰命名,如果类名前两个字母为大写那么就是这个类名本身
在这里插入图片描述


bean注解:
方法注解要搭配类注解使用,命名默认为方法名
在这里插入图片描述在这里插入图片描述

Spring扫描路径:

Spring扫描路径是启动类所在路径,的子路径及子孙路径一直往后扫描
在这里插入图片描述


修改后演示:
在这里插入图片描述
发现其路径,刚开始的”HelloController“都启动不了:
在这里插入图片描述


也可以通过注解手动修改启动类路径:@ComponentScan
在这里插入图片描述

什么是DI:

DI就是依赖注入,它是一个过程,就是把Spring管理的依赖就是对象,拿出来再注入到指定的属性中

DI的常用方法:

1.属性注入:

通过注解@Autowired来实现:
在这里插入图片描述


需要注入的属性1


需要注入的属性2


结果:
在这里插入图片描述

2.构造方法注入:

构造方法注入需要注意:
当有一个构造方法时,没得选可以注入成功,但是有多个构造方法时注入由于反射机制去获取无参数的构造方法


有多个构造方法时,由于反射机制,会去选择无参数的构造方法导致对象没有注入
在这里插入图片描述


这个时候就需要加上@Autowired注解,选中使用的构造方法:
在这里插入图片描述

3.set方法注入:

在set方法加上@Autowired注解就行:
在这里插入图片描述在这里插入图片描述

@Autowired存在的问题:

@Autowired注解通过类型来找到对象,如果有多个对象,就会报错:因为@Autowired注解首先按照类型来找对象的,找到多个对象不知道使用哪个
在这里插入图片描述

解决措施:

1.加上@Qualifier注解进一步通过名称来找bean:

@Qualifier注解不能单独使用,必须配合@Autowired使用


在这里插入图片描述在这里插入图片描述

2.加上@Primary注解:

@Primary,没有参数,所以使用在多个对象那一级来指定
在这里插入图片描述


指定:
在这里插入图片描述
在这里插入图片描述

3.加上@Resource注解:

@Resource注解:直接通过name属性来指定要注入的bean名称:


在这里插入图片描述在这里插入图片描述在这里插入图片描述

面试题:@Resource和@Autowired的区别:

面试官喜欢听到的回答:按照类型来
1.@Autowird注解是Spring提高的注解,而@Resource注解是jdk提供的
2.@Resource按照名称注入,@Autowired按照类型注入,@Resource支持更多参数设置,按照name属性来找bean


拓展:@Resource不完全按照名称查找,也需要在类型的基础上按照名称查找

@Autowired的装配顺序:

首先按照类型找bean,找不到抛异常,找到一个装配;如果找到多个对象时按照@Qualifier查找,我们找到@Qualifier是按照名称来找bean的,所以@Autowired准确来说是按照“类型+名称”来注入对象的
在这里插入图片描述


http://www.niftyadmin.cn/n/5864506.html

相关文章

内网网络安全的解决之道

本文简要分析了企业内部网络所面临的主要分析&#xff0c;阐述了安全管理人员针对不同威胁的主要技术应对措施。进一步介绍了业界各种技术措施的现状&#xff0c;并提出了未来可能的发展趋势。 内网网络安全问题的提出 网络安全对于绝大多数人而言指的都是互联网安全&#xff…

【Blender】二、建模篇--07,置换修改器

0 00:00:03,620 --> 00:00:08,620 大家好 这张课呢 我们来讲建模篇的最后一个重点修改器 置换修改器 1 00:00:08,980 --> 00:00:17,580 把它放在最后 不是因为它最难 而是因为它很常用 尤其大家以后做材质的时候 我们可以用一张贴图把一个平面做出来凹凸的感觉 2 00:00…

mysql中union all和WITH ROLLUP实现汇总的两种方式

目录 一、场景需求 二、UNION ALL实现方式 三、WITH ROLLUP实现方式 四、对比总结 一、场景需求 假设存在销售记录表sales&#xff1a; CREATE TABLE sales (sale_date DATE,product VARCHAR(50),amount DECIMAL(10,2) );需要实现&#xff1a;1. 按日统计总销售额 2. 按产…

Docker挂载数据显式挂载和隐式挂载的区别

项目使用的Docker file 创建数据卷挂载点&#xff0c;结果发现宿主机目录中的数据卷路径下是空的&#xff0c;才知道docker file中创建的数据卷是隐式挂载&#xff0c;并不会在宿主机上留下持久化数据&#xff0c;随着容器被删除隐式挂载的数据卷也会跟着被删除 后面改为在jen…

php处理图片出现内存溢出(Allowed memory size of 134217728 bytes exhausted)

错误&#xff1a; 最近做图片上传功能时发现上传某些图片时报内存溢出错误。如下所示&#xff1a; {"code": 0,"msg": "Allowed memory size of 134217728 bytes exhausted (tried to allocate 24576 bytes)","data": {"code&q…

智慧废品回收小程序php+uniapp

废品回收小程序&#xff1a;数字化赋能环保&#xff0c;开启资源循环新时代 城市垃圾治理难题&#xff0c;废品回收小程序成破局关键 随着城市化进程加速与消费水平提升&#xff0c;我国生活垃圾总量逐年攀升&#xff0c;年均增速达5%-8%&#xff0c;其中超30%为可回收物。然…

《2024工业控制系统网络安全态势白皮书》

一、白皮书发布背景 东北大学“谛听”网络安全团队近日撰写并发布了2024年工业控制网络安全态势白皮书&#xff0c;读者可以通过报告了解2024年工控安全相关政策法规报告及典型工控安全事件分析。 二、白皮书主要内容 报告对工控系统漏洞、联网工控设备、工控蜜罐与威胁情报…

【CSS】---- CSS 变量,实现样式和动画函数复用

1. 前言 本文介绍 CSS 的自定义属性(变量)来实现样式、动画等 CSS 的复用。都是知道在 CSS 和 JS 复用一个很重要的事情,比如 JS 的函数封装,各个设计模式的使用等等,CSS 中样式的复用,同样重要。MDN 使用 CSS 自定义属性(变量):自定义属性(有时候也被称作CSS 变量或…