Spring两大核心思想 IoC和AoP

目录

✨ 一、什么是IoC

1、定义 🎊

2、IoC思想 🎊

3、优势 🎊

4、对象的管理 🎊

存对象:@Component

取对象:@AutoWired 

✨二、什么是DI 

1、定义 🎊

2、IoC和DI的关系🎊

可以说DI是IoC的一种实现

✨三、IoC&DI的使用 

1、实现实例:用@Component注解实现存 🎊

2、 使用@AutoWired注解实现从容器中取对象🎊

✨四、IoC详解 

1、Bean的存储(类注解)🎊

1) @Controller(控制器存储)(控制层,接受请求,对请求进行处理,并进行响应)

从容器中获取对象:Spring上下文

2)@Service(服务存储)(业务逻辑层,处理具体的业务逻辑) 

​编辑 

3)Repository(仓库存储)(数据访问层,也称为持久层,负责数据的访问操作)

4)Component(组件存储)

5)Configuration(配置存储)(配置层,处理项目中的一些配置信息)

 2、Bean的命名🎊

 3、获取bean对象的方法(是父类(BeanFactory)提供的功能)🎊

常见的面试题: ApplicationContext VS BeanFactory

 4、方法注解(@Bean)🎊

1、一个对象的情况 

2、多个对象的情况 

 3、重命名Bean

5、扫描路径🎊

✨五、DI详解 

1、依赖注入的三种方法 🎊

1)属性注入(Field Injection)Autowired

2) 构造方法注入(Constructor Injection)

3)Setter注入(Setter Jniection)

2、三种注入的优缺点分析 🎊

3、@Autowired存在问题(当同一类型存在多个bean时)🎊


让我们先回顾一下什么是Spring:Spring是一个开源框架,他让我们的开发更简单,简单来说,Spring是包含了众多工具的IoC容器。

那么问题来了,什么是容器?什么是IoC容器?

容器是用来容纳某种物品的(基本)装置

  • List/Map ->数据存储器
  • Tomact -> Web容器

 一、什么是IoC

1、定义 

  Inversion of Control(控制反转),也就是说“Spring”是一个控制反转容器。

当需要某个对象时,传统的开发模式中需要new来创建对象,现在不需要再进行创建了,把创建对象的任务交给容器,由Spring来负责对象的创建和销毁,程序只需要依赖注入(Dependency Injection,DI) 就可以了。

这个容器称为:IoC容器。Spring是一个IoC容器,有时候Spring也称为Spring容器。(容器里面装的是对象,Spring管理的对象称之为bean

2、IoC思想 

     像我们之前写代码,在类上面添加@RestController和@Controller注解,就是把这个对象交给Spring来管理,Spring框架启动时就会加载该类,把对象交给Spring管理,就是IoC思想。 

3、优势 

资源不由使用资源的双方管理,而由不使用资源的第三方管理。

  1. 资源集中管理:IoC容器会帮我们管理一些资源(对象等),需要时,只需要从IoC容器中去取就可以了
  2. 我们在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,也就是耦合度。 

4、对象的管理 

  1. 存对象:@Component

  2. 取对象:@AutoWired 

二、什么是DI 

1、定义 

 Dependency Injection,DI(依赖注入),容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。

2、IoC和DI的关系

可以说DI是IoC的一种实现

可以看出,依赖注入和控制反转是从不同的角度的描述同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。 

三、IoC&DI的使用 

1、实现实例:用@Component注解实现存 

@Component
public class BookDao {
    public List<BookInfo> mockBookData() {
        List<BookInfo> bookInfos = new ArrayList<>();
        for(int i = 1;i < 15; i++) {
            BookInfo bookInfo = new BookInfo();
            bookInfo.setId(i);
            bookInfo.setBookName("图书" + i);
            bookInfo.setAuthor("作者" + i);
            bookInfo.setCount(i*15 + 3);
            bookInfo.setPrice(new BigDecimal(new Random().nextInt(100)));
            bookInfo.setPublish("出版社" + i);
            bookInfo.setStatus(i%5==0?2:1);
            bookInfos.add(bookInfo);
        }

        return bookInfos;
    }
}
@Component
public class BookService {
    /**
     * 根据数据层返回的结果对数据进行处理
     * @return
     */
    //从Spring中获取对象
    @Autowired
    private BookDao bookDao;
    public List<BookInfo> bookInfoList(){
        List<BookInfo> bookInfos = bookDao.mockBookData();
        for(BookInfo bookInfo: bookInfos) {
            if(bookInfo.getStatus()==1) {
                bookInfo.setStateCN("可借阅");
            }else if(bookInfo.getStatus()==2){
                bookInfo.setStateCN("不可借阅");
            }
        }
        return bookInfos;
    }
}

2、 使用@AutoWired注解实现从容器中取对象

@Autowired
    private BookDao bookDao;

四、IoC详解 

1、Bean的存储(类注解)

通过前面 学习,我们知道了把某个对象交给IoC容器进行管理,需要在类上添加一个注解,而Spring也提供了更丰富的注解。

类注解:@Controller、@Service(服务存储)、@Component(组件存储)、@Repository(仓库存储)、@Configuration(配置存储)

方法注解:@Bean

设置这么多类注解目的是为了让程序员看到类注解之后,就直接了当的了解当前类的用途

1) @Controller(控制器存储)(控制层,接受请求,对请求进行处理,并进行响应)

看下面例子:使用 @Controller存储bean的代码

package com.example.example1.controller;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    public void sayHi() {
        System.out.println("祝你好运,小李");
    }
}

如何观察这个对象已经存在在Spring容器中了呢?

@SpringBootApplication
public class Example1Application {

    public static void main(String[] args) {
        //获取Spring上下文对象
       ApplicationContext context = SpringApplication.run(Example1Application.class, args);
       //从Spring上下文中获取对象
        UserController userController = context.getBean(UserController.class);
        //使用对象
        userController.sayHi();
    }

}

运行程序: 

但如果删除@Controller,观察运行结果: 

 

从容器中获取对象:Spring上下文

 上下文:就是指当前的运行环境,也可以看做是一个容器,容器里面存了很多内容,这些内容是当前的运行的环境。

ApplicationContext context = SpringApplication.run(Example1Application.class, args);

2)@Service(服务存储)(业务逻辑层,处理具体的业务逻辑) 

package com.example.example1.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void sayHi() {
        System.out.println("祝你幸福快乐,小李");
    }
}
  //获取Spring上下文对象
       ApplicationContext context = SpringApplication.run(Example1Application.class, args);       
       UserService userService = context.getBean(UserService.class);
       userService.sayHi();

 

3)Repository(仓库存储)(数据访问层,也称为持久层,负责数据的访问操作)

4)Component(组件存储)

5)Configuration(配置存储)(配置层,处理项目中的一些配置信息)

 2、Bean的命名

程序开发人员不需要为bean指定名称 ,如果没有显示的提供名称,Spring容器将为该Bean生成唯一的名称

来看spring官方文档中说明:Bean Overview :: Spring Framework

 

 3、获取bean对象的方法(是父类(BeanFactory)提供的功能)

package com.example.example1;

import com.example.example1.controller.UserController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Example1Application {

    public static void main(String[] args) {
        //获取Spring上下文对象
       ApplicationContext context = SpringApplication.run(Example1Application.class, args);
       //从Spring上下文中获取对象,根据类型
        UserController userController1 = context.getBean(UserController.class);
        //根据名称
        UserController userController2 = (UserController) context.getBean("userController");
        //根据类型+名称
        UserController userController3 = context.getBean("userController", UserController.class);
 System.out.println(userController1);
        System.out.println(userController2);
        System.out.println(userController3);
    }

}

 

常见的面试题: ApplicationContext VS BeanFactory

  • 继承关系和功能方面来说:Spring容器有两个顶级的接口:BeanFactory和ApplicationContext。其中前者提供了基础的访问容器的能力,后者属于 BeanFactory的子类,他除了继承了BeanFactory的所有功能之外,它还具有独特的特性,还添加了对国际化支持、资源访问支持、以及事件传播等方面的支持。
  • 性能方面:后者是一次性加载并初始化所有的Bean对象,而前者是需要哪个才去加载哪个,因此更加轻量(空间换时间)

 4、方法注解(@Bean)

考虑以下场景:1、使用外部包里面的类,没办法添加类注解

2、一个类,需要多个对象,比如多个数据源 

1、一个对象的情况 

 示例:

package com.example.example1.bean;

import lombok.Data;

import javax.lang.model.element.NestingKind;
@Data
public class User {
    private String name;
    private int age;
}
package com.example.example1.bean;
import org.springframework.context.annotation.Bean;

public class BeanConfig {
    @Bean
    public User user(){
        User user = new User();
        user.setName("zhangsan");
        user.setAge(12);
        return user;
    }
}

 

User user = context.getBean(User.class);
        System.out.println(user);

 让我查看运行结果,结果报错了

什么原因造成的呢?

在Spring框架的设计中,方法注解@Bean要配合类注解才能将对象正常的存储到Spring容器中

对上述代码进行修改

package com.example.example1.bean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class BeanConfig {
    @Bean
    public User user(){
        User user = new User();
        user.setName("zhangsan");
        user.setAge(12);
        return user;
    }
}

再次运行:

2、多个对象的情况 

 

从运行结果可以看出:@Bean注解的Bean,bean名称就是它的方法名

所以我们根据名称来获取bean对象 

 3、重命名Bean

    @Bean(name = {"u3","user3"})
    public User user3(){
        User user = new User();
        user.setName("wangwu");
        user.setAge(14);
        return user;
    }
 User u3 = (User) context.getBean("u3");
        System.out.println(u3);

 

5、扫描路径

问题:使用前面学过的四个注解声明Bean,一定会生效吗?

答案是不一定的,bean要想生效,还需要被Spring扫描 

  1. 通过@CompontentScan 

@ComponentScan({"com.example.example1"}) 

五、DI详解 

 依赖注入是一个过程,是指IoC在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象,之前,我们使用@Autowired这个注解,完成了依赖注入的操作

简单来说,就是把对象取出来放到某个类属性中

1、依赖注入的三种方法 

1)属性注入(Field Injection)Autowired

@Controller
public class UserController {
    @Autowired
    private UserService userService;
    public void sayHi() {
        System.out.println("祝你好运,小李");
        userService.sayHi();
    }
}

 

@Service
public class UserService {
    public void sayHi() {
        System.out.println("祝你幸福快乐,小李");
    }
}
      UserController userController = (UserController) context.getBean("userController");
        userController.sayHi();

 

2) 构造方法注入(Constructor Injection)

 

package com.example.example1.controller;

import com.example.example1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {
    private UserService userService;
    @Autowired
    public UserController2 (UserService userService) {
        this.userService = userService;
    }
    public void sayHi() {
        System.out.println("祝你好运,小李");
        userService.sayHi();
    }
}

注意:如果类只有一个构造方法,那注解可以省略,反之则不行 

3)Setter注入(Setter Jniection)

2、三种注入的优缺点分析 

• 属性注⼊ ◦:

优点: 简洁,使⽤⽅便;

◦ 缺点: ▪ 只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指 针异常) ▪ 不能注⼊⼀个Final修饰的属性

• 构造函数注⼊(Spring 4.X推荐)

◦ 优点: ▪ 可以注⼊final修饰的属性 ▪ 注⼊的对象不会被修改 ▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法. ▪ 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的

◦ 缺点: ▪ 注⼊多个对象时, 代码会⽐较繁琐

• Setter注⼊(Spring 3.X推荐)

◦ 优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊

◦ 缺点: ▪ 不能注⼊⼀个Final修饰的属性 ▪ 注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险. 

3、@Autowired存在问题(当同一类型存在多个bean时)

@Autowird 与 @Resource的区别

• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解

• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊.

相⽐于 @Autowired 来说, @Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/761720.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion【真人模型】:人脸特美的人像摄影大模型wuhaXL_realisticMixV3.0

今天和大家分享一个基于SDXL的真人大模型&#xff1a;wuhaXL_realisticMix。该模型无需使用LORA**就能生成的特别漂亮的人脸&#xff0c;虽然有时候人脸有些假&#xff0c;但是生成的人脸确实非常漂亮。 该模型底模融合了WhiteXL_realisticMix&#xff0c;训练素材来自于视频转…

nacos开启认证之后,服务就无法注册了

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

机器学习项目-基于随机森林的航空公司用户满意度分析

摘要 ​ 航空旅行是人们出行的常用方式之一&#xff0c;乘客对于航空公司的服务质量有着较高的要求。满意度是衡量服务质量的重要指标&#xff0c;因此预测航空公司乘客的满意度对于提高服务质量具有重要意义。 ​ 近年来&#xff0c;机器学习在预测领域得到了广泛应用。机器…

08 - Python面向对象编程进阶

面向对象进阶 在前面的章节我们已经了解了面向对象的入门知识&#xff0c;知道了如何定义类&#xff0c;如何创建对象以及如何给对象发消息。为了能够更好的使用面向对象编程思想进行程序开发&#xff0c;我们还需要对Python中的面向对象编程进行更为深入的了解。 property装…

mst[讲课留档]

最小生成树(Minimum Spanning Tree) (1)概念 我们知道&#xff0c;树是有 n n n个结点&#xff0c; n − 1 n-1 n−1条边的无向无环的连通图。 一个连通图的生成树是一个极小的连通子图&#xff0c;它包含图中全部的 n n n个顶点&#xff0c;但只有构成一棵树的 n − 1 n-1 …

SAP实现特别总账的凭证预制

SAP实现特别总账的凭证预制 仔细理解只有”其他”的特殊总帐标识才可预制凭证这句话. F-29/f-48不可预制。F-29/f-48预制时出现错误消息号 FP 030&#xff0c;提示特殊总帐标志类型“汇票和”预付定金“的特别总帐标志的过帐代码不能预制&#xff0c;这是系统写死的&#xff…

骨传导耳机哪个牌子好?精选靠谱好用的TOP5骨传导耳机推荐!

在超过八成的音乐爱好者都面临听力健康问题的当下&#xff0c;骨传导耳机因其独特的听觉体验和对听力的保护&#xff0c;在音频设备市场中备受瞩目。但近期我发现不少用户在选购骨传导耳机时常常受到不专业产品的误导。身为有着5年经验的数码博主&#xff0c;在此提醒大家&…

Web基础与HTTP协议:

Web基础与HTTP协议 Web&#xff1a;就是我们所说的页面&#xff0c;打开网站所展示的页面。&#xff08;全球广域网&#xff0c;万维网&#xff09; 分布式图形信息系统。 http https &#xff08;加密的&#xff09;超文本传输协议 分布式&#xff1a;计算机系统或者应用程序…

数据分析与挖掘案例-电子商务网站用户行为分析及服务推荐

数据分析与挖掘案例-电子商务网站用户行为分析及服务推荐 文章目录 数据分析与挖掘案例-电子商务网站用户行为分析及服务推荐1. 背景与挖掘目标2. 分析方法与过程2.1 分析步骤与流程2.2 数据抽取2.3 数据探索分析1. 分析网页类型2. 分析网页点击次数 2.4 数据预处理1. 删除不符…

《昇思25天学习打卡营第23天 | 昇思MindSporeRNN实现情感分类》

23天 本节学习了RNN实现情感分类。 循环神经网络&#xff08;RNN&#xff09;是一类以序列&#xff08;sequence&#xff09;数据为输入&#xff0c;在序列的演进方向进行递归&#xff08;recursion&#xff09;且所有节点&#xff08;循环单元&#xff09;按链式连接的神经网…

C++视觉开发 一.OpenCV环境配置

一.OpenCV安装环境配置 1.OpenCV安装 &#xff08;1&#xff09;下载 官方下载链接&#xff1a;http://opencv.org/releases 这边选择需要的版本&#xff0c;我是在windows下的4.9.0。&#xff08;科学上网下载很快&#xff0c;否则可能会有点慢&#xff09; (2)安装 双击下…

【深度学习】图生图img3img论文原理,SD EDIT

https://arxiv.org/abs/2108.01073 摘要 引导图像合成技术使普通用户能够以最小的努力创建和编辑逼真的图像。关键挑战在于平衡对用户输入&#xff08;例如&#xff0c;手绘的彩色笔画&#xff09;的忠实度和合成图像的真实感。现有的基于GAN的方法试图通过使用条件GAN或GAN反…

【CT】LeetCode手撕—93. 复原 IP 地址

目录 题目1- 思路2- 实现⭐93. 复原 IP 地址——题解思路 3- ACM 实现 题目 原题连接&#xff1a;93. 复原 IP 地址 1- 思路 模式识别&#xff1a;给一个 String 字符串 ——> 复原 IP 地址 ——> 回溯三部曲 &#xff0c;回溯的切割问题 ——> 实现一个左闭右闭区间…

小白入门云计算的最佳方式,是去考一张AWS证书

云计算的快速发展让它成为现代IT行业的核心技术之一。 作为一名初学者&#xff0c;如何高效地入门云计算&#xff1f; 我的建议是&#xff1a;考一张AWS证书。 AWS&#xff08;Amazon Web Services&#xff09;在云计算市场占据领先地位&#xff0c;它的认证体系既权威又全面&a…

实现Ubuntu计划任务的反弹shell

一、实验环境 Ubuntu&#xff1a;IP地址&#xff1a;192.168.223.156 Kali : IP地址&#xff1a;192.168.223.152 二、编写crontab计划任务 在Ubuntu的系统中使用crontab -e命令编写计划任务&#xff0c;如下所示&#xff1a; 作用&#xff1a;是将一个交互式的bash …

Kubernetes的发展历程:从Google内部项目到云原生计算的基石

目录 一、起源与背景 1.1 Google的内部项目 1.2 Omega的出现 二、Kubernetes的诞生 2.1 开源的决策 2.2 初期发布 三、Kubernetes的发展历程 3.1 社区的成长 3.2 生态系统的壮大 3.3 重大版本和功能 3.4 多云和混合云的支持 四、Kubernetes的核心概念 4.1 Pod 4.…

vscode 安装Vue插件

打开扩展面板 --> 点击左侧的扩展图标&#xff0c;或者按下快捷键 Ctrl Shift X 搜索插件,在搜索框中输入 Vue vue-helper 用来快捷提示&#xff0c;如果使用elementui的话&#xff0c;插件不会自动提示&#xff0c;安装了它&#xff0c;组件、属性都会有提示了 Vetur V…

硬核丨2024文本生成类AI产品横向评测报告

文本生成/写作”作为使用最高频的AI场景&#xff0c;各类产品如雨后春笋般出现。我们针对办公/学习的写作场景进行了全面系统的评测。希望此次评测结论能够帮您在工作学习中使用AI应用提效。 本次评测对象包含文心、通义、kimi等模型厂商及笔灵、迅捷、秘塔等应用厂商共13款产…

制造业如何拥抱数字化?百数服务商的转型策略与实践

制造业作为实体经济的主体部分&#xff0c;也是核心部分&#xff0c;发挥着基础性、主导性和引领性作用。推动制造业数字化转型是实现经济高质量发展的必由之路。 在这场数字化浪潮中&#xff0c;低代码平台作为一种新兴的技术手段&#xff0c;逐渐受到了企业的青睐。其能够在…

国产压缩包工具——JlmPackCore SDK说明(一)

一、什么是JlmPackCore SDK &#xff08;1&#xff09;自主可控 JlmPackCore是一套基于我国自主知识产权的核心算法发明专利——杰林码&#xff08;详系请参考《杰林码原理及应用》一书&#xff0c;也可以参考后续发表的相关论文&#xff09;&#xff0c;其中一篇会议论文&…