Java课题笔记~ IoC 控制反转

二、IoC 控制反转

控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的 装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。

IoC 是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现 方式是依赖注入。应用广泛。

依赖:classA 类中含有 classB 的实例,在 classA 中调用 classB 的方法完 成功能,即 classA 对 classB 有依赖。

Ioc 的实现:

依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些 工作由容器自行完成。

依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在 代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。

Spring 的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象 之间依赖关系的管理。

Spring 框架使用依赖注入(DI)实现 IoC。

Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。Spring 容器管理着容器中 Bean 之间的依赖关系, Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。使用 IoC 实现 对象之间的解耦和。

1、开发工具准备

开发工具:idea2017 以上

依赖管理:maven3 以上

jdk:1.8 以上

需要设置 maven 本机仓库:

 

2、Spring 的第一个程序

举例:spring-quickstart

2.1 创建 maven 项目

 

2.2 引入 maven 依赖 pom.xml

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.8.RELEASE</version></dependency>
</dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins>
</build>

2.3  定义接口与实体类

public interface SomeService {void doSome();
}public class SomeServiceImpl implements SomeService {public SomeServiceImpl() {super();System.out.println("SomeServiceImpl无参数构造方法");}@Overridepublic void doSome() {System.out.println("====业务方法doSome()===");}
}

2.4  创建 Spring 配置文件

在 src/main/resources/目录现创建一个 xml 文件,文件名可以随意,但 Spring 建议的名称为 applicationContext.xml

spring 配置中需要加入约束文件才能正常使用,约束文件是 xsd 扩展名。

 

<bean />:用于定义一个实例对象。一个实例对应一个 bean 元素。

id:该属性是 Bean 实例的唯一标识,程序通过 id 属性访问 Bean,Bean 与 Bean 间的依赖关系也是通过 id 属性关联的。

class:指定该 Bean 所属的类,注意这里只能是类,不能是接口。

2.5  定义测试类

 

2.6  使用 spring 创建非自定义类对象

spring 配置文件加入 java.util.Date 定义:

<bean id="myDate" class="java.util.Date" />

MyTest 测试类中:

调用 getBean(“myDate”); 获取日期类对象。

2.7  容器接口和实现类

ApplicationContext 接口(容器)

ApplicationContext 用于加载 Spring 的配置文件,在程序中充当“容 器”的角色。其实现类有两个。

 

 

A、 配置文件在类路径下

若 Spring 配置文件存放在项目的类路径下,则使用 ClassPathXmlApplicationContext 实现类进行加载。

 

B、ApplicationContext 容器中对象的装配时机

ApplicationContext 容器,会在容器对象初始化时,将其中的所有对象一 次性全部装配好。以后代码中若要使用到这些对象,只需从内存中直接获取即 可。执行效率较高。但占用内存。

 C、使用 spring 容器创建的 java 对象

 

3、基于 XML 的 DI

举例:项目 di-xml

3.1 注入分类

bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初 始化。初始化是由容器自动完成的,称为注入。

根据注入方式的不同,常用的有两类:set 注入、构造注入。

(1) set 注入(掌握)

set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种 注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

A、 简单类型

 

 

创建 java.util.Date 并设置初始的日期时间:

Spring 配置文件:

 测试方法:

 

B、引用类型

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引 用关系。ref 的值必须为某 bean 的 id 值。

 测试方法:

 

(2) 构造注入(理解)

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即, 使用构造器设置依赖关系。

举例 1:

 

<constructor-arg />标签中用于指定参数的属性有:

  • name:指定参数名称。

  • index:指明该参数对应着构造器的第几个参数,从 0 开始。不过,该属性 不要也行,但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺 序要与构造器中的参数顺序一致。

举例 2:

使用构造注入创建一个系统类 File 对象

 

3.2  引用类型属性自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为 标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默 认是不自动注入引用类型属性)。根据自动注入判断标准的不同,可以分为两 种:

  • byName:根据名称自动注入

  • byType: 根据类型自动注入

(1) byName 方式自动注入

当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相 同时,可使用 byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。容器是通过调用者的 bean 类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

举例:

 

(2) byType 方式自动注入

使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属 性指定的类,要与代码中调用者 bean 类的某引用类型属性类型同源。即要么 相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

举例:

 

3.3  为应用指定多个 Spring 配置文件

在实际应用里,随着应用规模的增加,系统中 Bean 数量也大量增加,导 致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的 可读性与可维护性,可以将 Spring 配置文件分解成多个配置文件。

包含关系的配置文件:

多个配置文件中有一个总文件,总配置文件将各其它子文件通过<import />引入。在 Java 代码中只需要使用总配置文件对容器进行初始化即可。

举例:

代码:

 Spring 配置文件:

 也可使用通配符 * 。但,此时要求父配置文件名不能满足*所能匹配的格 式,否则将出现循环递归包含。就本例而言,父配置文件不能匹配 spring- *.xml 的格式,即不能起名为 spring-total.xml。

 

4、 基于注解的 DI

举例:di-annotation 项目

对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。 Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。

需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描 注解。

 

 

指定多个包的三种方式:

1)使用多个 context:component-scan 指定不同的包路径

2)指定 base-package 的值使用分隔符

分隔符可以使用逗号(,)分号(;)还可以使用空格,不建议使用空格。

 

3)base-package 是指定到父包名

base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当 然也会扫描到子包下级的子包。所以 base-package 可以指定一个父包就可以。

 但不建议使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。指定 到目标包和合适的。也就是注解所在包全路径。例如注解的类在 com.bjpowernode.beans 包中

 

4.1  定义 Bean 的注解@Component(掌握)

需要在类上使用注解@Component,该注解的 value 属性用于指定该 bean 的 id 值。

举例:di01

 

另外,Spring 还提供了 3 个创建对象的注解:

  • @Repository 用于对 DAO 实现类进行注解

  • @Service 用于对 Service 实现类进行注解

  • @Controller 用于对 Controller 实现类进行注解

这三个注解与@Component 都可以创建对象,但这三个注解还有其他的 含义,@Service 创建业务层对象,业务层对象可以加入事务功能, @Controller 注解创建的对象可以作为处理器接收用户的请求。

@Repository,@Service,@Controller 是对@Component 注解的细 化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。

@Component 不指定 value 属性,bean 的 id 是类名的首字母小写。

 

4.2  简单类型属性注入@Value(掌握)

需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的 值。

使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter, 则也可将其加到 setter 上。

举例:

 

4.3  byType 自动注入@Autowired(掌握)

需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装 配 Bean 的方式。

使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter, 则也可将其加到 setter 上。

举例:

 

4.4  byName 自动注入@Autowired 与@Qualifier(掌握)

需要在引用属性上联合使用注解@Autowired 与@Qualifier。@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。

举例:

  @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败 后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配 的属性值为 null。

 

 4.5  JDK 注解@Resource 自动注入(掌握)

Spring 提供了对 jdk 中@Resource 注解的支持。@Resource 注解既可以 按名称匹配 Bean,也可以按类型匹配 Bean。默认是按名称注入。使用该注 解,要求 JDK 必须是 6 及以上版本。@Resource 可在属性上,也可在 set 方 法上。

(1) byType 注入引用类型属性

@Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不 能注入 bean,则会按照类型进行 Bean 的匹配注入。

举例:

 

(2) byName 注入引用类型属性

@Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹 配的 Bean 的 id。

举例:

4.6  注解与 XML 的对比

注解优点是:

  • 方便

  • 直观

  • 高效(代码少,没有配置文件的书写那么复杂)。

其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新 编译代码的。

XML 方式优点是:

  • 配置和代码是分离的

  • 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。

XML 的缺点是:编写麻烦,效率低,大型项目过于复杂。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为react项目添加开发/提交规范(前端工程化、eslint、prettier、husky、commitlint、stylelint)

因历史遗留原因&#xff0c;接手的项目没有代码提醒/格式化&#xff0c;包括 eslint、pretttier&#xff0c;也没有 commit 提交校验&#xff0c;如 husky、commitlint、stylelint&#xff0c;与其期待自己或者同事的代码写得完美无缺&#xff0c;不如通过一些工具来进行规范和…

FFmpeg中硬解码后深度学习模型的图像处理dnn_processing(一)

ffmpeg 硬件解码 ffmpeg硬件解码可以使用最新的vulkan来做&#xff0c;基本上来说&#xff0c;不挑操作系统是比较重要的&#xff0c;如果直接使用cuda也是非常好的选择。 AVPixelFormat sourcepf AV_PIX_FMT_NV12;// AV_PIX_FMT_NV12;// AV_PIX_FMT_YUV420P;AVPixelFormat d…

SpringBoot+SSM实战<一>:打造高效便捷的企业级Java外卖订购系统

文章目录 项目简介项目架构功能模块管理端用户端 技术选型用户层网关层应用层数据层工具 项目优缺点结语 黑马程序员最新Java项目实战《苍穹外卖》&#xff1a;让你轻松掌握SpringBootSSM的企业级开发技巧项目简介 《苍穹外卖》是一款为餐饮企业&#xff08;餐厅、饭店&#x…

zookeeper --- 基础篇

一、zookeeper简介 1.1、什么是zookeeper zookeeper官网&#xff1a;https://zookeeper.apache.org/ 大数据生态系统里的很多组件的命名都是某种动物或者昆虫&#xff0c;他是用来管 Hadoop&#xff08;大象&#xff09;、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理…

Spring Cloud Gateway

一 什么是Spring Cloud Gateway 网关作为流量的入口&#xff0c;常用的功能包括路由转发&#xff0c;权限校验&#xff0c;限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架&#xff0c;定位于取代 Netflix Zuul。相比 Zuul 来说&#xff0c;Spring Clo…

redis 集群 2:分而治之 —— Codis

在大数据高并发场景下&#xff0c;单个 Redis 实例往往会显得捉襟见肘。首先体现在内存上&#xff0c;单个 Redis 的内存不宜过大&#xff0c;内存太大会导致 rdb 文件过大&#xff0c;进一步导致主从同步时全量同步时间过长&#xff0c;在实例重启恢复时也会消耗很长的数据加载…

ROS添加节点

1 下载项目源码 &#xff08;1&#xff09;这里我使用是哔哩哔哩的博主源码机器人工匠王杰 https://github.com/6-robot/wpr_simulation.git &#xff08;2&#xff09;建立工作空间 在主目录下载建立如下文件夹 catkin_ws----       ----src &#xff08;3&#xff09;…

express学习笔记4 - 热更新以及express-boom

我们每次改动代码的时候都要重启项目&#xff0c;现在我们给项目添加一个热更新 npm install --save-dev nodemon # or using yarn: yarn add nodemon -D 在package.json添加一行代码 "dev": "nodemon ./bin/www" 重启项目 然后随便做改动&#xff…

多线程(JavaEE初阶系列7)

目录 前言&#xff1a; 1.常见的锁策略 1.1乐观锁和悲观锁 1.2轻量级锁和重量级锁 1.3自旋锁和挂起等待锁 1.4互斥锁与读写锁 1.5可重入锁与不可重入锁 1.6公平锁与非公平锁 2.CAS 2.1什么是CAS 2.2自旋锁的实现 2.3原子类 3.synchronized 3.1synchronized的原理以…

K8S系列文章之 内外网如何互相访问

K8S中网络这块主要考虑 如何访问外部网络以及外部如何访问内部网络 访问外网服务的两种方式 需求 k8s集群内的pod需要访问mysql&#xff0c;由于mysql的性质&#xff0c;不适合部署在k8s集群内,故k8s集群内的应用需要链接mysql时&#xff0c;需要配置链接外网的mysql,本次测试…

记一次 .NET某医疗器械清洗系统 卡死分析

一&#xff1a;背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题&#xff0c;回过头来看这个案例比较经典&#xff0c;这篇稍微整理一下供后来者少踩坑吧。 二&#xff1a;WinDbg 分析 1. 为什么会卡死 因为是窗体程序&#xff0c;理所当然就是看主…

代理模式——对象的间接访问

1、简介 1.1、概述 由于某些原因&#xff0c;客户端不想或不能直接访问某个对象&#xff0c;此时可以通过一个被称为“代理”的第三者来实现间接访问&#xff0c;该方案对应的设计模式被称为代理模式。 代理模式是一种应用很广泛的结构型设计模式&#xff0c;而且变化很多。…

【我们一起60天准备考研算法面试(大全)-第三十六天 36/60】【最短路】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

SpringCloud Gateway 在微服务架构下的最佳实践

作者&#xff1a;徐靖峰&#xff08;岛风&#xff09; 前言 本文整理自云原生技术实践营广州站 Meetup 的分享&#xff0c;其中的经验来自于我们团队开发的阿里云 CSB 2.0 这款产品&#xff0c;其基于开源 SpringCloud Gateway 开发&#xff0c;在完全兼容开源用法的前提下&a…

java中的hashmap和concurrenthashmap解析

hashmap的初始化数组大小为16&#xff0c;如果发生哈希冲突的时候在当前的索引后面采用头插法以链表的形式继续插入节点。 concurrenthashmap的结构图如下所示&#xff1a; 本身不是16个节点吗&#xff1f;这里分为两个长度为4的数组&#xff0c;变成了4*4总共16个节点&#x…

决策树与随机森林

目录 决策树是&#xff1a;Why&#xff1a;How&#xff1a;基本概念决策树生成举例决策树缺点参考 Demo 随机森林1.是&#xff1a;2.Why&#xff1a;3.How&#xff1a;参考 Demo 决策树 是&#xff1a; 1.一种有监督的分类&#xff08;或预测&#xff09;算法。 2.利用属性、…

网络安全--原型链污染

目录 1.什么是原型链污染 2.原型链三属性 1&#xff09;prototype 2)constructor 3)__proto__ 4&#xff09;原型链三属性之间关系 3.JavaScript原型链继承 1&#xff09;分析 2&#xff09;总结 3)运行结果 4.原型链污染简单实验 1&#xff09;实验一 2&#xff0…

使用hutool工具生成树形结构

假设要构建一个菜单&#xff0c;可以实现智慧库房&#xff0c;菜单的样子如下&#xff1a; 智慧库房|- RFID|- 智慧大屏|- 智能密集架|- 环境管控那这种结构如何保存在数据库中呢&#xff1f;一般是这样的&#xff1a; ​ 每条数据根据parentId相互关联并表示层级关系&#x…

Killing LeetCode [83] 删除排序链表中的重复元素

Description 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 Intro Ref Link&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ Difficulty&#xff1a;Easy Tag&am…

云上 Index:看「简墨」如何为云原生打造全新索引

拓数派首款数据计算引擎 PieCloudDB Database 是一款全新的云原生虚拟数仓。为了提升用户使用体验&#xff0c;提高查询效率&#xff0c;在实现存算分离的同时&#xff0c;PieCloudDB 设计与打造了全新的存储引擎「简墨」等模块&#xff0c;并针对云场景和分析型场景设计了高效…