【学习】Spring IoCDI

2024-04-12 19:12
文章标签 java 学习 spring iocdi

本文主要是介绍【学习】Spring IoCDI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 🎥 个人主页:Dikz12
  • 📕格言:吾愚多不敏,而愿加学
  • 欢迎大家👍点赞✍评论⭐收藏

目录

Spring 是什么?

什么是 IoC容器?

传统开发模式 

loC开发模式

IoC的优势 

IoC 的使用

Bean的存储 

 方法注解

 DI

 属性注入

 构造⽅法注⼊

 Setter 注⼊

@Autowired存在的问题

 解决方案:

 @Autowired和@Resource的区别


Spring 是什么?

 Spring是一个开发应用框架,其目的是用于简化企业级应用程序开发. Springd的原生框架指的是Spring Core、Spring FrameWork; 这个概念是比较抽象的,可以用一句更具体的话来概述:Spring是包含众多工具的 IoC容器.

什么是 IoC容器?

“容器”通常指的是一种可以用来盛放物品的器皿;⽣活中的⽔杯,垃圾桶,冰箱等等这些都是容器,像 List/ Map就是数据存储的容器、Tomcat 就是Web容器;

IoC:Inversion of Control (控制反转),也是Spring两大核心思想之一. 也就是说: Spring是⼀个"控制反转"的容器.

什么是控制反转?

也就是控制权反转,获取依赖对象的过程被反转了,当需要 某个对象时,传统开发模式中需要自己通过new创建对象,现在不需要在进行创建,而是把这个创建对象的任务交给了容器. 程序只需要依赖注入(DI)就可以. 这个容器就是IoC容器.

IoC是一种思想,在生活中也有体现:

比如:传统的驾驶方式,车辆的控制权需要由驾驶员来控制,而现在就可以把驾驶权交给自动化系统来控制。

IoC是一种思想,DI是一种实现方式!

传统开发模式 

 设计轮⼦(Tire),然后根据轮⼦的⼤⼩设计底盘(Bottom),接着根据底盘设计⻋⾝(Framework),最后根据⻋⾝设计好整个汽⻋(Car)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底盘依赖轮⼦.

public class Main {public static void main(String[] args) {Car car = new Car(17);car.run();}
}static class FrameWork {private Bottom bottom;public FrameWork(int size) {bottom = new Bottom(size);}
}static class Bottom {private Tire tire;public Bottom(int size) {tire = new Tire(size);System.out.println("Bottom...init..");}
}static class Tire {public int size;private String color;public Tire(int size) {this.size = size;System.out.println("tire....init...size:"+size);}
}

 从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改.程序的耦合度⾮常⾼(修改⼀处代码,影响其他处的代码修改)

loC开发模式

把调⽤汽⻋的程序⽰例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式.
 

public class Main {public static void main(String[] args) {Tire tire= new Tire(17,"red");Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}
}

代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了.

IoC的优势 

  1. 资源集中管理,实现资源的可配置和易管理。
  2. 降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度(解耦)。

IoC 的使用

Bean的存储 

 共有两类注解类型可以实现:

  • 1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
  • 2. ⽅法注解:@Bean.
@Controller //把这个对象交给Spring进行管理
public class UserController {public void hello() {System.out.println("Hello,Controller");}
}

 获取对象:

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

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

 方法注解

类注解是添加到某个类上的,但是存在两个问题:

  • 1. 使⽤外部包⾥的类,没办法添加类注解
  • 2. ⼀个类,需要多个对象,⽐如多个数据源

这种场景,我们就需要使⽤⽅法注解@Bean.

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

@Bean 方法注解要搭配类注解一起使用,否则就是报错!! 可以对Bean对象进行重命名操作.

 DI

 依赖注⼊是⼀个过程,是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源,⽽资源指的就是对象.

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

  • 1. 属性注⼊
  • 2. 构造⽅法注⼊
  • 3. Setter注⼊

 属性注入

 属性注⼊是使⽤@Autowired注解实现的. 比如:将Service 类注⼊到 Controller类中.

@Controller //把这个对象交给Spring进行管理
public class UserController {@Autowiredprivate UserService userService;public void hello() {System.out.println("Hello,Controller");userService.hello();}
}
@Service
public class UserService {public void hello() {System.out.println("Hello,UserService...");}
}

 构造⽅法注⼊

@Controller
public class UserController2 {//注⼊⽅法2: 构造⽅法private UserService userService;public UserController2() {}@Autowiredpublic UserController2(UserService userService) {this.userService = userService;}public void hi(){System.out.println("hi,UserController2...");userService.hello();}
}

去掉@Autowired,就会报异常,如下:

 如果类只有⼀个构造⽅法,那么,@Autowired注解可以省略;如果类中有多个构造⽅法,那么需要添加上@Autowired来明确指定到底使⽤哪个构造⽅法。

 Setter 注⼊

@Controller
public class UserController3 {//注⼊⽅法3: Setter⽅法注⼊private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void hello() {System.out.println("hello,UserController3...");userService.hello();}
}

如果去掉@Autowired的话,就会报空指针异常!

@Autowired存在的问题

 当同⼀类型存在多个bean时,使⽤@Autowired会存在问题.

 

会出两个bean对象,非唯一的bean对象,Spring就不知道要用那个了,直接就启动失败! 

 解决方案:

1.修改@Autowired的属性名跟Bean的名称一致.

 

 2.使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.

3. 使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean的名称。 @Qualifier注解不能单独使⽤,必须配合@Autowired使⽤.

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

 @Autowired和@Resource的区别

  1.  @Autowired默认是以类型注入的,当同一个类型有多个对象,也会按名称进行匹配,如果名称匹配不到,就会报错;@Resource 是按照名称注入的,使用name指定注入。
  2. @Autowired是由Spring提供的注解;@Resource是JDK提供的注解。

这篇关于【学习】Spring IoCDI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/897995

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2