Spring IoC DI

 博主主页: 码农派大星.

    数据结构专栏:Java数据结构

 数据库专栏:MySQL数据库

JavaEE专栏:JavaEE

关注博主带你了解更多数据结构知识

目录

1. 应用分层

1.1 如何分层:

1.2 MVC与三层架构区别联系

2. Spring

3.IoC & DI⼊⻔

3.1 什么是IoC?

3.2 DI 介绍 

4.IoC 使⽤

4.1 类注解区别

4.2 ⽅法注解@Bean

4.2.1⽅法注解要配合类注解使⽤

4.2.2 定义多个对象 

4.2.3 重命名Bean 

5. DI 依赖注入

5.1 属性注⼊

5.2 构造方法注入 

5.3 Setter 注⼊ 

5.4 三种注⼊优缺点 

属性注⼊

构造函数注⼊

 Setter注⼊

5.5 @Autowired存在问题

@Primary

@Qualifier

@Resource 

 @Resource 和@Autowired区别

6.Spring, Spring Boot和SpringMVC的关系以及区别 


1. 应用分层

应⽤分层是⼀种软件开发设计思想,它将应⽤程序分成N个层次,这N个层次分别负责各⾃的职责,多个层次之间协同提供完整的功能.根据项⽬的复杂度,把项⽬分成三层,四层或者更多层,之前为了让项⽬快速上线,我们通常是不考虑分层的.但是随着业务越来越复杂,⼤量的 代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题.所以学习对项⽬进⾏分层对我们来说就是很有必要的了.

1.1 如何分层:

我们上一篇博客中学的Spring MVC中就把整体的系统分成了Model(模型),View(视图)Controller(控制器)三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构

对于我们后端开发来说,我们可以把整体架构分为表现层、业务逻辑层和数据层.这种分层⽅式也称之为"三层架构"

1. 表现层:就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;(请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据)

2. 业务逻辑层:负责处理业务逻辑, ⾥⾯有复杂业务的具体实现;(逻辑处理:负责业务逻辑处理的代码)

3. 数据层: 负责存储和管理与应⽤程序相关的数据(数据访问:负责业务数据的维护操作,包括增、删、改、查等操作.)

在Spring中我们把这三层分别分为:

Controller:控制层,接收前端发送的请求,对请求进⾏处理,并响应数据。

Service:业务逻辑层,处理具体的业务逻辑。

Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查

1.2 MVC与三层架构区别联系

MVC 是一种设计模式,用于分离应用程序的用户界面(UI)和业务逻辑,强调用户界面和业务逻辑的分离,使得开发者可以专注于单一方面的开发,而不必担心其他部分的实现细节

三层架构是一种软件架构模式,强调应用程序的不同功能层之间的分离,使得每一层都可以独立开发和测试

MVC 更侧重于用户界面的实现和业务逻辑的分离,而三层架构侧重于整个应用程序的分层和模块化

MVC模式强调数据和视图分离,将数据展⽰和数据处理分开,通过控制器对两者进⾏组合. 三层架构强调不同维度数据处理的⾼内聚和低耦合,将交互界⾯,业务处理和数据库操作的逻辑分开

联系:提高代码的可维护性和可扩展性,⼆者的⽬的是相同的,都是"解耦,分层,代码复⽤"

可测试性:通过分离不同的功能到不同的层或组件,两者都使得单元测试和集成测试变得更加容易。

可维护性:在 MVC 和三层架构中,代码的组织方式使得维护和更新变得更加简单

2. Spring

Spring就是包含了众多⼯具⽅法的IoC容器

3.IoC & DI⼊⻔

3.1 什么是IoC?

IoC 是Spring的核⼼思想,其实IoC我们在前⾯已经使⽤了,我们在前⾯讲到,在类上⾯添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类.把对象交 给Spring管理,就是IoC思想.

IoC: Inversion of Control (控制反转),也就是说Spring是⼀个"控制反转"的容器

什么是控制反转呢? 也就是控制权反转.什么的控制权发⽣了反转? 获得依赖对象的过程被反转了 也就是说,当需要某个对象时,传统开发模式中需要⾃⼰通过new创建对象,现在不需要再进⾏创 建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊(DI)就可以了. 这个容器称为:IoC容器. Spring是⼀个IoC容器,所以有时Spring也称为Spring容器

控制反转是⼀种思想,在⽣活中也是处处体现. ⽐如⾃动驾驶, 传统驾驶⽅式,⻋辆的控制权由驾驶员行驶来控制,现在交给了驾驶自动化系统来控制,这也是控制反转思想在⽣活中的实现

IoC容器具备优点:

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

2. 我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度

3.2 DI 介绍 

DI就是依赖注入

它是实现 IoC一种设计模式。依赖注入的主要思想是将组件的依赖关系(即它所依赖的对象或资源)通过外部传递给它,而不是让组件自己创建或查找这些依赖

DI 是 IoC 的一种实现方式,它专注于解决对象之间的依赖关系。在 DI 中,一个对象(称为消费者)所依赖的另一个对象(称为服务提供者)不是由消费者自己创建的,而是由 IoC 容器在运行时动态注入到消费者中

4.IoC 使⽤

类注解:@Controller、@Service、@Repository、@Component、@Configuration.
⽅法注解:@Bean

4.1 类注解区别

@Controller:控制层,接收请求,对请求进⾏处理,并进⾏响应.
@Servie:业务逻辑层,处理具体的业务逻辑.
@Repository:数据访问层,也称为持久层.负责数据访问操作
@Configuration:配置层.处理项⽬中的⼀些配置信息

我们发现@Service、@Repository、@Configuration.中都包含@Component说明这些注解本身属于@Component的“子类”。

4.2 ⽅法注解@Bean

1.使⽤外部包⾥的类, 没办法添加类注解

2. ⼀个类,需要多个对象,⽐如多个数据源

4.2.1⽅法注解要配合类注解使⽤

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
}
public static void main(String[] args) {
		ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
		UserInfo bean = context.getBean(UserInfo.class);
		System.out.println(bean);

	}

 

4.2.2 定义多个对象 

定义多个对象运行会报错,对象不唯一,运行失败

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }
}

 可以看出来, @Bean注解的bean,bean的名称就是它的⽅法名

@Bean可以针对同⼀个类,定义多个对象,但我们得根据他们的名称来获取bean对象 

Object userInfo1 = context.getBean("userInfo1");
		System.out.println(userInfo1);

4.2.3 重命名Bean 

可以通过设置name属性给Bean对象进⾏重命名操作,name={} 可以省略,也可以重命名多个名字

public class UserInfoComonent {

    @Bean(name = {"cxk","zhangsan"})
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
    @Bean(name = "mjq")
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }

	public static void main(String[] args) {
		ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
		
		Object userInfo1 = context.getBean("cxk");
		System.out.println(userInfo1);


	}

5. DI 依赖注入

依赖注⼊,Spring给我们提供了三种⽅式:

1. 属性注⼊

2. 构造⽅法注⼊

3. Setter 注⼊

5.1 属性注⼊

属性注⼊是使⽤ @Autowired 实现的,将Service类注⼊到Controller类中

@Service
public class UserService {


    public void say(){
        System.out.println("UserService say....");

    }
}
@Controller
public class UserCotroller {
    @Autowired
    private UserService userService;

    public void say(){
        System.out.println("UserController say....");
        userService.say();
    }
}
UserCotroller bean = context.getBean(UserCotroller.class);
bean.say();

5.2 构造方法注入 

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如果类只有⼀个构造⽅法,那么@Autowired 注解可以省略

@Controller
public class UserCotroller {
  

    private UserService userService;

    public UserCotroller(UserService userService) {
        this.userService = userService;
    }

    public void say(){
        System.out.println("UserController say....");
        userService.say();
    }
}

 

如果存在多种构造方法需要添加上@Autowired 来明确指定到底使⽤哪个构造⽅法 

@Controller
public class UserCotroller {
  
    private UserService userService;


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

    @Autowired
    public UserCotroller(UserService userService) {
        this.userService = userService;
        System.out.println("有参构造");
    }

    public void say(){
        System.out.println("UserController say....");
        userService.say();
    }
}

5.3 Setter 注⼊ 

Setter 注⼊和属性的Setter⽅法实现类似,只不过在设置set⽅法的时候需要加上@Autowired 注解

@Controller
public class UserCotroller {
  
   private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }


    public void say(){
        System.out.println("UserController say....");
        userService.say();
    }
}

5.4 三种注⼊优缺点 

属性注⼊

优点:简洁,使⽤⽅便

缺点:只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指 针异常)

 不能注⼊⼀个Final修饰的属性

构造函数注⼊

优点: 

可以注⼊final修饰的属性

注⼊的对象不会被修改

依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法.

通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的

缺点:

注⼊多个对象时,代码会⽐较繁琐

 Setter注⼊

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

缺点:

不能注⼊⼀个Final修饰的属性

注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的风险

5.5 @Autowired存在问题

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }
}

当同⼀类型存在多个对象时,按照名称来匹配,该类型只有一个对象时,直接注入;有多个对象时,按照名称注入

@Primary

当存在多个相同类型的Bean注⼊时,加上@Primary注解,确定哪个是默认的实现

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
   @Primary
    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }

    @Bean
    public UserInfo userInfo2() { return new UserInfo("cxk",34);}
}

@Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean 的名称

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

@Component
public class UserComponent {

   @Qualifier("userInfo2")
    @Autowired
    private UserInfo ui;

    public void say(){
        System.out.println("UserComponent say.... ");
        System.out.println(ui);
    }
}
@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }


    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }

    @Bean
    public UserInfo userInfo2() { return new UserInfo("cxk",34);}
}

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }
    
    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }
    @Bean
    public String name(){
        return "cxk";
    }
    @Bean
    public String name1(){
        return "mjq";
    }
    @Bean
    public UserInfo userInfo2(@Qualifier("name") String name3) { return new UserInfo(name3,34);}
}

 

 

@Resource 

@Resource注解:是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称

@Component
public class UserInfoComonent {

    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",29);
    }

    @Bean
    public UserInfo userInfo1(){
        return new UserInfo("lisi",23);
    }
}
@Component
public class UserComponent {

    @Resource(name = "userInfo1")
    private UserInfo ui;

    public void say(){
        System.out.println("UserComponent say.... ");
        System.out.println(ui);
    }
}

 @Resource 和@Autowired区别

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

@Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired 来说, @Resource ⽀持更多的参数设置,例如name设置,根据名称获取Bean.

@Autowired根据类型匹配,@Resource根据名称匹配,优先按照类型匹配,如果同类型右多个对象,再按照名称匹配,它两基本原则都是根据类型匹配,但是@Autowired不能指定名称

6.Spring, Spring Boot和SpringMVC的关系以及区别 

Spring: 简单来说,Spring是⼀个开发应⽤框架,什么样的框架呢,它轻量级、⼀ 站式、模块化,其⽬的是⽤于简化企业级应⽤程序开发,Spring的主要功能:管理对象,以及对象之间的依赖关系,⾯向切⾯编程,数据库事务管理,数据访 问,web框架⽀持等,但是Spring具备⾼度可开放性,并不强制依赖Spring,开发者可以⾃由选择Spring的部分或者全 部,Spring可以⽆缝继承第三⽅框架,⽐如MyBaties

Spring MVC:SpringMVC是Spring的⼀个⼦框架,Spring诞⽣之后,⼤家觉得很好⽤,于是按照MVC 模式设计了⼀个MVC框架(⼀些⽤Spring解耦的组件),主要⽤于开发WEB应⽤和⽹络接⼝,所以, Spring MVC是⼀个Web框架.Spring MVC基于Spring进⾏开发的,天⽣的与Spring框架集成.可以让我们更简洁的进⾏Web层 开发,⽀持灵活的URL到⻚⾯控制器的映射,提供了强⼤的约定⼤于配置的契约式编程⽀持,⾮常 容易与其他视图框架集成

Spring Boot: Spring Boot是对Spring的⼀个封装,为了简化Spring应⽤的开发⽽出现的,使⽤SpringBoot可以更加快速的搭建框架,降级开发成本,让开发 ⼈员更加专注于Spring应⽤的开发,⽽⽆需过多关注XML的配置和⼀些底层的实现 

SpringMVC和SpringBoot都属于Spring,SpringMVC是基于Spring的⼀个 MVC框架,⽽SpringBoot是基于Spring的⼀套快速开发整合包

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

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

相关文章

CANFD SSP第二采样点引发的“风波”分析

案例背景: 近几年来,主机厂逐渐大范围使用CANFD通信。在CAN网络中,因SSP第二采样点引发的错误帧偶有发生,所以在主机厂的SPEC需求中,明确要求启用CAN控制器的TDC收发器延迟补偿, 目录 1 CANFD的SSP第二采…

【设计模式】《Java 设计模式魔法:解锁高效编程的秘密武器》

标题:《Java 设计模式奇幻之旅:解锁高效编程的魔法钥匙》 摘要: 本文将深入探讨 Java 中的十种设计模式,包括单例模式、工厂方法模式、抽象工厂模式…迭代器模式、组合模式、模板方法模式等。通过详细的解释、生动有趣的例子以及…

【skywalking 】选择Elasticsearch存储

介绍 skywalking支持 Elasticsearch 和 OpenSearch 作为存储。 OpenSearch 是 ElasticSearch 7.11 的一个分支,但在 Apache 2.0 中获得许可。 OpenSearch 存储与 ElasticSearch 共享相同的配置。为了激活 OpenSearch 作为存储,请将存储提供程序设置为e…

Python4

4. 更多控制流工具 除了刚介绍的 while 语句&#xff0c;Python 还用了一些别的。我们将在本章中遇到它们。 4.1. if 语句 if elif else if x<0: x 0 print(Negative changed to zero) elif x0: print( zero) else: print(More) 4.2. for 语句 Pyth…

Mybatis的关联关系-多对多

在进行数据库原理的时候&#xff0c;我们将E-R图的实体转化为我们的表时&#xff0c;有时要考虑到多对多的关系。比如下图&#xff1a; 我们可以转化为下面的表&#xff1a; 因为User和Orders是1:n的关系&#xff0c;所以Orders有一个外键。 t_orders表 idnumberuser_id(外键…

uniapp使用easyinput文本框显示输入的字数和限制的字数

uniapp使用easyinput文本框显示输入的字数和限制的字数 先上效果图&#xff1a; 整体代码如下&#xff1a; <template><view class"nameInfoContent"><uni-easyinput class"uni-mt-5" suffixIcon"checkmarkempty" v-model&quo…

Redis 事务 总结

前言 相关系列 《Redis & 目录》&#xff08;持续更新&#xff09;《Redis & 事务 & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Redis & 事务 & 总结》&#xff08;学习总结/最新最准/持续更新&#xff09;《Redis & 事务…

基础数据结构及算法——AVL树【自平衡二叉搜索树】解决失衡

历史 AVL 树是一种自平衡二叉搜索树&#xff0c;由托尔哈斯特罗姆在 1960 年提出并在 1962 年发表。它的名字来源于发明者的名字&#xff1a;Adelson-Velsky 和 Landis&#xff0c;他们是苏联数学家&#xff0c;于 1962 年发表了一篇论文&#xff0c;详细介绍了 AVL 树的概念和…

VoLTE 微信令:SBC 功能篇之 超长呼叫释放信令流程

目录 1. SBC 的位置及超长呼叫释放功能简介 2. VoLTE 超长通话,SBC 释放呼叫流程 博主wx:yuanlai45_csdn 博主qq:2777137742 想要 深入学习 5GC IMS 等通信知识(加入 51学通信),或者想要 cpp 方向修改简历,模拟面试,学习指导都可以添加博主低价指导哈。 1. SBC 的位置及…

使用 Python 的 BeautifulSoup(bs4)解析复杂 HTML

使用 Python 的 BeautifulSoup&#xff08;bs4&#xff09;解析复杂 HTML&#xff1a;详解与示例 在 Web 开发和数据分析中&#xff0c;解析 HTML 是一个常见的任务&#xff0c;尤其是当你需要从网页中提取数据时。Python 提供了多个库来处理 HTML&#xff0c;其中最受欢迎的就…

华尚实业集团家居产业园总部中心项目奠基仪式成功举办

金秋风景如画&#xff0c;十月天高云淡。良辰阳光灿烂&#xff0c;吉时热闹非凡。2024年10月23日上午&#xff0c;华尚实业集团家居产业园总部中心项目奠基仪式在增城经济技术开发区宁西园区项目现场隆重举行&#xff0c;标志着华尚实业集团家居产业园总部中心建设正式拉开帷幕…

基于Java语言的充电桩管理系统

介绍 云快充协议云快充1.5协议云快充协议开源代码云快充底层协议云快充桩直连桩直连协议充电桩系统桩直连协议 软件架构 1、提供云快充底层桩直连协议&#xff0c;版本为云快充1.5&#xff0c;对于没有对接过充电桩系统的开发者尤为合适&#xff1b; 2、包含&#xff1a;启…

安卓项目复制修改包名称打包失败处理——android studio

处理方法 将资源包名称直接替换为新的包名称&#xff0c;不管错误直接生成。

skynet的cluster集群

集群的使用 现在的游戏服务器框架中&#xff0c;分布式是一种常见的需求。一个游戏服务器组通常可以分成网关服务器、登录服务器、逻辑服务器、跨服服务器等等。 在skynet中&#xff0c;我们可以通过cluster来组建一个集群&#xff0c;实现分布式的部署。 示例 我们先来看一…

Win11安装基于WSL2的Ubuntu

1. 概述 趁着还没有完全忘记&#xff0c;详细记录一下在Win11下安装基于WSL2的Ubuntu的详细过程。不得不说WSL2现在被微软开发的比较强大了&#xff0c;还是很值得安装和使用的&#xff0c;笔者就通过WSL2安装的Ubuntu成功搭建了ROS环境。 2. 详论 2.1 子系统安装 在Win11搜…

在Debian上安装向日葵

说明&#xff1a; 因为之前服务器上安装了 PVE (Proxmox VE)&#xff0c;之前是用 Proxmox VE 进行服务器资源管理的。出于某些原因&#xff0c;现在不再通过 PVE构建的虚拟机来使用计算资源&#xff0c;而是通过 PVE 自带的 Debian 系统直接使用虚拟机资源&#xff08;因为积…

NVR接入录像回放平台EasyCVR视频融合平台语音对讲配置

国标GB28181视频平台EasyCVR视频融合平台可拓展性强、视频能力灵活&#xff0c;平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析接入等功能。其中&#xff0c;在语音对讲方面&#xff0c;NVR接入录像回放平台目前…

JavaEE初阶---多线程(三)---内存可见性/单例模式/wait,notify的使用解决线程饿死问题

文章目录 1.volatile关键字1.1保证内存的可见性--引入1.2保证内存的可见性--分析1.3保证内存的可见性--解决1.4内存可见性-JMM内存模型 2.notify和wait介绍2.1作用一&#xff1a;控制调度顺序2.2作用二&#xff1a;避免线程饿死2.3notify和notifyAll区分 3.单例模式--经典设计模…

数据库编程 SQLITE3 Linux环境

永久存储程序数据有两种方式&#xff1a; 用文件存储用数据库存储 对于多条记录的存储而言&#xff0c;采用文件时&#xff0c;插入、删除、查找的效率都会很差&#xff0c;为了提高这些操作的效率&#xff0c;有计算机科学家设计出了数据库存储方式 一、数据库 用来管理数据…

【Android】多渠道打包配置

目录 简介打包配置签名配置渠道配置配置打包出来的App名称正式包与测试包配置 打包方式开发工具打包命令行打包 优缺点 简介 多渠道打包 是指在打包一个 Android 应用时&#xff0c;一次编译生成多个 APK 文件&#xff0c;每个 APK 文件针对一个特定的渠道。不同的渠道可能代表…