免费发布网站建设的平台,element ui做的网站,wordpress分页 标题,网站编程赚钱#x1f493; 博客主页#xff1a;从零开始的-CodeNinja之路
⏩ 收录文章#xff1a;Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
#x1f389;欢迎大家点赞#x1f44d;评论#x1f4dd;收藏⭐文章 目录 前提小知识:高内… 博客主页从零开始的-CodeNinja之路
⏩ 收录文章Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
欢迎大家点赞评论收藏⭐文章 目录 前提小知识:高内聚低耦合一. IOC1.1 什么是IOC1.2 IOC的实现1.3 IOC容器的优点1.4 IOC的存储Controller控制器存储Service服务存储Repository仓库存储Component组件存储Configuration配置存储Bean (方法注解) 1.5 IOC注解总结概括 二. DI2.1 什么是DI?2.2 DI的方法使用属性注入构造方法注入Setter注入三种注入优缺点分析 2.3 Autowired存在的问题PrimaryQualifierResource 2.4 Autowird的注入流程图 三. 总结 前提小知识:高内聚低耦合
我们一下要学习的内容都是为了实现⾼内聚低耦合来进行的 软件设计原则⾼内聚低耦合. ⾼内聚指的是⼀个模块中各个元素之间的联系的紧密程度如果各个元素(语句、程序段)之间的联 系程度越⾼则内聚性越⾼即⾼内聚。 低耦合指的是软件中各个层、模块之间的依赖关联程序越低越好。修改⼀处代码,其他模块的代码 改动越少越好. ⾼内聚低耦合⽭盾吗? 不⽭盾,⾼内聚指的是⼀个模块中各个元素之间的联系的紧密程度,低耦合指的是各个模块之间的紧 密程度 这就好⽐⼀个企业,包含很多部⻔,各个部⻔之间的关联关系要尽可能的⼩,⼀个部⻔发⽣问题,要尽 可能对降低对其他部⻔的影响,就是耦合.但是部⻔内部员⼯关系要尽量紧密,遇到问题⼀起解决,克 服.这叫做内聚. ⽐如邻⾥邻居,楼上漏⽔,楼下遭殃,就是耦合.家庭⼀个成员⽣病,其他成员帮忙照顾,就叫内聚. ⼀个家庭内部的关系越紧密越好,⼀个家庭尽可能少的影响另⼀个家庭,就是低耦合. 简单来说:就是在未来的工作中写出的代码尽量集中在一个路径中,但是每个程序与其它程序的关联度很低,以至于一个文件出错了并不影响其它程序的正常运行.
一. IOC
1.1 什么是IOC
IoC是Spring的核⼼思想,也是常⻅的⾯试题,那什么是IoC呢? IoC:InversionofControl(控制反转),也就是说Spring是⼀个控制反转的容器. 什么是控制反转呢?也就是控制权反转.什么的控制权发⽣了反转?获得依赖对象的过程被反转了 也就是说,当需要某个对象时,传统开发模式中需要⾃⼰通过new创建对象,现在不需要再进⾏创 建,把创建对象的任务交给容器,程序中只需要依赖注⼊(DependencyInjection,DI)就可以了. 我们⽤⼀句更具体的话来概括Spring,那就是:Spring是包含了众多⼯具⽅法的IoC容器 简单点来说:就是通过IOC的内置注解将被注解的内容放到Spring的大池子里,方便后续的调用(这样子应该很好理解)
1.2 IOC的实现
举个栗子:比如传统的造车过程是一级级的调用,如下: 以上程序的问题是当最底层代码改动之后整个调⽤链上的所有代码都需要修改.程序的耦合度⾮常⾼(修改⼀处代码,影响其他处的代码修改)
经过IOC实现后的流程图如下: 而IOC的目标就是为了降低耦合度,对于上面的例子来说就是将汽车每个部件的生产都交给第三方来处理,不让他们之间有联系,也就降低了耦合度 我们发现了⼀个规律通⽤程序的实现代码类的创建顺序是反的传统代码是Car控制并创建了 FrameworkFramework创建并创建了Bottom依次往下⽽改进之后的控制权发⽣的反转不再 是使⽤⽅对象创建并控制依赖对象了⽽是把依赖对象注⼊将当前对象中依赖对象的控制权不再由 当前类控制了. 这样的话,即使依赖类发⽣任何改变当前类都是不受影响的这就是典型的控制反转也就是IoC的 实现思想。
1.3 IOC容器的优点
资源不由使⽤资源的双⽅管理⽽由不使⽤资源的第三⽅管理这可以带来很多好处。第⼀资源集 中管理实现资源的可配置和易管理。第⼆降低了使⽤资源双⽅的依赖程度也就是我们说的耦合 度。
资源集中管理:IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取 就可以了我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度. Spring就是⼀种IoC容器,帮助我们来做了这些资源管理.
1.4 IOC的存储
在之前的⼊⻔案例中要把某个对象交给IOC容器管理需要在类上添加⼀个注解 Component ⽽Spring框架为了更好的服务web应⽤程序,提供了更丰富的注解. 共有两类注解类型可以实现
类注解Controller、Service、Repository、Component、Configuration.⽅法注解Bean. 接下来我们分别来看
Controller控制器存储
使⽤Controller存储bean的代码如下所⽰ Controller // 将对象存储到 Spring 中public class UserController {public void sayHi(){System.out.println(hi,UserController...);}}Service服务存储
使⽤Service存储bean的代码如下所⽰ Service// 将对象存储到 Spring 中public class UserService {public void sayHi(String name) {System.out.println(Hi, name);}}Repository仓库存储
使⽤ Repository 存储bean的代码如下所⽰ Repositorypublic class UserRepository {public void sayHi() {System.out.println(Hi, UserRepository~);}}Component组件存储
使⽤Component存储bean的代码如下所⽰ Componentpublic class UserComponent {public void sayHi() {System.out.println(Hi, UserComponent~);}}Configuration配置存储
使⽤Configuration存储bean的代码如下所⽰ Configurationpublic class UserConfiguration {public void sayHi() {System.out.println(Hi,UserConfiguration~);}}Bean (方法注解)
类注解是添加到某个类上的同时⽅法注解要配合类注解使⽤但是存在两个问题:
使⽤外部包⾥的类,没办法添加类注解⼀个类,需要多个对象,⽐如多个数据源 这种场景,我们就需要使⽤⽅法注解 Bean 我们先来看看⽅法注解如何使⽤: ⽅法注解要配合类注解使⽤
Component
public class BeanConfig {Beanpublic User user(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}
}1.5 IOC注解总结概括 Controller控制层,接收请求,对请求进⾏处理,并进⾏响应. Servie业务逻辑层,处理具体的业务逻辑. Repository数据访问层也称为持久层.负责数据访问操作 Configuration配置层.处理项⽬中的⼀些配置信息. Component:其它4大类注解的父类 Bean:方法注解,将一个方法交给Spring管理,同时要与类注解一起搭配使用
其实这些注解⾥⾯都有⼀个注解 Component 说明它们本⾝就是属于 Component 的⼦类.Component 是⼀个元注解也就是说可以注解其他类注解如 Controller , Service , Repository 等.这些注解被称为 Component 的衍⽣注解. Controller , Service 和 Repository ⽤于更具体的⽤例(分别在控制层,业务逻辑层,持 久化层),在开发过程中,如果你要在业务逻辑层使⽤ Component 或Service显然Service是更 好的选择
二. DI
2.1 什么是DI?
DI:DependencyInjection(依赖注⼊) 容器在运⾏期间,动态的为应⽤程序提供运⾏时所依赖的资源称之为依赖注⼊。 程序运⾏时需要某个资源此时容器就为其提供这个资源. 从这点来看,依赖注⼊DI和控制反转IoC是从不同的⻆度的描述的同⼀件事情就是指通过 引⼊IoC容器利⽤依赖关系注⼊的⽅式实现对象之间的解耦。 上述代码中,是通过构造函数的⽅式,把依赖对象注⼊到需要使⽤的对象中的 可以说,DI是IoC的⼀种实现
2.2 DI的方法使用
依赖注⼊是⼀个过程是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源⽽资源指的就是对象. 在上⾯程序案例中我们使⽤了 Autowired 这个注解完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中. 在⼀些⽂章中,依赖注⼊也被称之为对象注⼊,“属性装配”,具体含义需要结合⽂章的上下⽂来理解 关于依赖注⼊,Spring也给我们提供了三种⽅式:
属性注⼊(FieldInjection)构造⽅法注⼊(ConstructorInjection)Setter注⼊(SetterInjection)
属性注入
属性注⼊是使⽤ Autowired 实现的将Service类注⼊到Controller类中. Service类的实现代码如下
import org.springframework.stereotype.Service;
Service
public class UserService {public void sayHi() {System.out.println(Hi,UserService);}
}构造方法注入
构造⽅法注⼊是在类的构造⽅法中实现注⼊如下代码所⽰
Controller
public class UserController2 {//注⼊⽅法2: 构造⽅法private UserService userService;Autowiredpublic UserController2(UserService userService) {this.userService userService;}public void sayHi(){System.out.println(hi,UserController2...);userService.sayHi();}
}注意事项如果类只有⼀个构造⽅法那么Autowired注解可以省略如果类中有多个构造⽅法 那么需要添加上Autowired来明确指定到底使⽤哪个构造⽅法。
Setter注入
Setter注⼊和属性的Setter⽅法实现类似只不过在设置set⽅法的时候需要加上Autowired注 解如下代码所⽰
Controller
public class UserController3 {//注⼊⽅法3: Setter⽅法注⼊private UserService userService;Autowiredpublic void setUserService(UserService userService) {this.userService userService;}public void sayHi(){System.out.println(hi,UserController3...);userService.sayHi();}
}三种注入优缺点分析
属性注⼊
优点:简洁使⽤⽅便
缺点:
只能⽤于IoC容器如果是⾮IoC容器不可⽤并且只有在使⽤的时候才会出现NPE空指针异常不能注⼊⼀个Final修饰的属性
构造函数注⼊
优点:
可以注⼊final修饰的属性注⼊的对象不会被修改依赖对象在使⽤前⼀定会被完全初始化因为依赖是在类的构造⽅法中执⾏的⽽构造⽅法 是在类加载阶段就会执⾏的⽅法.通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的
缺点: 注⼊多个对象时,代码会⽐较繁琐
Setter注⼊
优点:⽅便在类实例之后,重新对该对象进⾏配置或者注⼊
缺点:
不能注⼊⼀个Final修饰的属性注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的⻛险.
2.3 Autowired存在的问题
当同⼀类型存在多个bean时,使⽤Autowired会存在问题 报错的原因是⾮唯⼀的Bean对象。 如何解决上述问题呢Spring提供了以下⼏种解决⽅案 • Primary • Qualifier • Resource
Primary
使⽤Primary注解当存在多个相同类型的Bean注⼊时加上Primary注解来确定默认的实现.
Component
public class BeanConfig {Primary //指定该bean为默认bean的实现Bean(u1)public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}Beanpublic User user2() {User user new User();user.setName(lisi);user.setAge(19);return user;}
}Qualifier
使⽤Qualifier注解指定当前要注⼊的bean对象。在Qualifier的value属性中指定注⼊的bean 的名称。 • Qualifier注解不能单独使⽤必须配合Autowired使⽤
Controller
public class UserController {Qualifier(user2) //指定bean名称Autowiredprivate User user;public void sayHi(){System.out.println(hi,UserController...);System.out.println(user);}
}Resource
使⽤Resource注解是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称。
Controller
public class UserController {Resource(name user2)private User user;public void sayHi(){System.out.println(hi,UserController...);System.out.println(user);}
}2.4 Autowird的注入流程图 常见⾯试题: Autowird与Resource的区别 • Autowired是spring框架提供的注解⽽Resource是JDK提供的注解 • Autowired默认是按照类型注⼊⽽Resource是按照名称注⼊.相⽐于Autowired来说 Resource⽀持更多的参数设置例如name设置根据名称获取Bean。
三. 总结
Java Spring框架中的IoCInversion of Control控制反转和DIDependency Injection依赖注入是框架的核心概念之一它们旨在降低组件之间的耦合度提高代码的灵活性和可维护性。 控制反转IoC在传统的程序设计中应用程序控制程序的流程即应用程序负责实例化和管理对象之间的依赖关系。而在IoC容器中控制权被转移到容器容器负责实例化对象并管理它们之间的依赖关系。这种控制权的转移使得组件之间的耦合度降低提高了代码的灵活性和可测试性。 依赖注入DI依赖注入是IoC的一种实现方式通过依赖注入容器会将一个对象所依赖的其他对象注入到该对象中而不是由对象自己去创建或查找依赖的对象。依赖注入可以通过构造函数、属性或者方法进行注入使得组件之间的依赖关系更加清晰、可控同时也方便进行单元测试和替换依赖。
总的来说IoC和DI通过将控制权交给容器实现了组件之间的解耦和松耦合提高了代码的可维护性、可测试性和可扩展性是Spring框架的核心特性之一。