Spring中IOC和AOP的深入讲解
作者:余同学的开发之路 发布时间:2023-11-19 10:20:59
前言
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置。
Spring 简介
Spring 是一个开源的轻量级的企业级框架,其核心是反转控制 (IoC) 和面向切面 (AOP) 的容器框架。我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象,所以 Spring 有很多强大的功能。
一句话,Spring 是项目中对象的管家,负责管理项目中用到的所有对象。所以在项目三层架构中,Spring 不属于某一特定层。
Spring 的 Hello World
想要构建一个 Spring 的入门程序,我们需要导入 4 个核心包和 2 个辅助包,创建一个实体类,最主要的是编写核心配置文件,applicationContext.xml 放在 src 下。最后写一个测试类即可。此时在测试类中我们不需要在使用 new 关键字去创建对象了。这也正是 Spring 的作用所在,会自动给我创建对象。
上图展示的就是最基本的演示,也是很容易就理解了,配置文件中配置了 user 对象,我们通过加载配置文件来获取对象从而避免了使用 new 来创建。
什么是 IOC
到这里我们就可以解释一下 Spring 中的核心概念之一的 IOC,即 inverse of control ,翻译过来就是反转控制。想想我们以前想要一个对象就会主动的 new 。现在 Spring 会帮我们创建对象,不需要手工 new(但是要记得配置呀)反转说的就是创建对象的方式反转了,以前是我们自己创建对象,现在由 Spring 为我们创建。
控制又是指什么呢?一个对象要有属性值吧,还有可能存在其它的对象,控制说的就是这些属性和引用不需要自己写了,由 Spring 来为我们自动创建(其实还是我们自己配置的~)。
总结下来就是 Spring 可以自动的为我们创建对象,并注入依赖。而反转控制说的就是以前我们自己创建对象和依赖,现在由程序为我们创建。
Spring 创建对象的方式
那 Spring 又是如何为我们创建的呢?我们知道对象的创建必须要经过构造器,从上面的例子中看到,我们只配置了一个<bean>标签,其实这就是将空参构造器使用配置文件给表示出来罢了。Spring 中创建对象也就是这么简单,当然配置可以更复杂些,后面再说,但目前我们可以知道,Spring 创建对象的就是通过配置 bean 标签,调用构造器来实现的。如何调用构造器的,那肯定是反射搞的鬼。
藏在 IOC 背后的 DI
DI,Dependency Injection,即依赖注入。IOC 还体现在自动注入依赖,依赖注入这词听起来不太明白,简单的理解为绑定数据,这是一种具体的技术,IOC 是思想,DI 是技术实现。对象之中需要其它的对象,类如 Service 层中需要 DAO 层对象,我们不需要在 Service 中手动 new 了,只需要配置一下即可。
常用的注入方式有两种,set 方法注入和构造方法注入。而每一种注入方式中又有注入基本数据类型和引用数据类型之分。下面就看看如何配置。
set 方法注入
通过 property 标签来配置属性,基本数据类型使用 value 属性即可,若是引用类型则使用 ref 。注意,User 对象中要有 Car 引用并且提供其 set 方法。
构造方法注入
这个配置看一眼就基本理解了,非常简单,说个小细节,对象的创建需要执行构造器,我们在初始化对象的时候会使用反射通过全类名得到对象,而这时就需要一个空参的构造器,我们不提供构造器的情况下,程序会自动为我们提供一个空参构造器,但是一旦重写构造器,我们就需要提供空参构造器,不然就报错。
虽然还有其它属性注入的方式,比方说 p 名称空间注入,spel 注入,但是这些都不重要!最常用的就一个那就是 set 方法注入。抓住重点,简单省时。
总结一下,以上主要说了什么是 Spring,如何搭建入门项目,解释了 IOC 思想,以及站在 IOC 背后的技术 DI,我们使用 set 方式注入基本数据类型和引用数据类型,当然,这些东西都构建在反射之上。
AOP 介绍
AOP 是我们经常听到的概念,然而听的太多我们却忘记了最初的定义,全称 Aspect Oriented Programming 翻译过来就是面向切面编程。首先,要搞清楚这是一种思想,Spring 的核心思想就有 AOP 。
尝试理解一下 AOP 的思想,简单来说就是“纵向重复,横向抽取”这很抽象,举几个例子,Filter 的思想,过滤器在解决乱码的时候不需要我们在每一个类中都写处理乱码的代码。而是直接由 Fliter 来统一处理。还有 * 的思想,我们在 Action 中需要对参数进行校验、封装,而 * 又是统一对参数进行校验、封装。
不管是 Fliter 还是 * ,都是面向切面编程思想的具体应用。而我们今天说的 Spring 中的 AOP 又是如何体现呢?
* 和 cglib 代理
那就是通过代理,Spring 中通过代理达到统一增强代理对象的目的,而不需要对类中的方法一个一个增强。我们以前接触过 * ,知道在 * 中我们的代理对象和被代理对象需要实现同一个接口,在 Spring 中无法保证每个需要增强的类都实现接口,所以就需要引用另外一种代理技术 cglib 代理。
总结一下就是 Spring 中通过代理来体现 AOP 的思想,而代理的实现又分为 * 和 cglib 代理。 * 要求代理类和被代理类实现同一个接口。而 cglib 是继承代理,代理对象只需继承被代理对象即可实现。在 Spring 中优先使用 * 。
两种代理方式有不同的测试代码,这里我不再展示,当我敲代码的时候我突然想到来上海第一次面试的时候,面试官就让我实现一下 Spring 中的 AOP,现在终于想通了,就是让我写一下两种代理方法的实现呀。可惜,当时一脸懵逼……
Spring 中与 AOP 相关名词
连接点(joinPoint): 在目标对象中,所有可以增强的方法。
切入点(pointCut): 在目标对象中,已经增强的方法。
增强/通知(advice): 增强的代码。
目标对象(target): 被代理对象。
织入(weaving): 将通知应用到到连接点。
代理(Proxy): 将通知织入到目标对象形成代理对象。
切面(aspect): 切入点+通知。
下面通过代码展示一下 Spring 中 AOP 的展示,顺带看看与这几个名词的对象关系。
上面的整个过程就是 Spring 中 AOP 的体现,将通知织入到目标对象中形成代理的这么一个过程。我们为了这个需要准备目标对象,通知对象,还要学会如何配置切点和切面。
上面只是为了测试一下能否正确的生成代理对象,而在 Spring 中真正应用 AOP 的是对事务的处理。Spring AOP 实质就是帮我们生成代理对象,而这个代理对象包含了对事务的处理。我们通过配置即可生成代理对象,而不需要我们再手敲代码处理事务。
在 Spring 中还提供了使用注解来配置,注释的出现就是为了替换配置文件,然而注释使用的不多。
总结一下,IoC 和 AOP 都是 Spring 中的核心概念,IoC 体现在 Spring 会为我们自动创建对象,由以前的手动 new 对象,到现在 Spring 统一管理。
我想到一个例子来说明一下 AOP,高速路上的收费站就是一个切面,Spring 的 IoC 就是一个发车站,负责维护汽车对象和依赖对象汽车上的人,车就是目标对象,而我们要生成的代理对象就是通过收费站的汽车。
来源:https://www.cnblogs.com/YJK923/p/10187076.html


猜你喜欢
- 安装Java:安装J2SE开发工具包5.0(JDK 5.0)下载:Java官方网站。请确保以下环境变量设置,如下所述:JAVA_HOME:
- 前面聊了布隆过滤器,回归认识一下位图BitMap,阅读前文的同学应该发现了布隆过滤器本身就是基于位图,是位图的一种改进。位图先看一个问题,
- 1、启动新Activty1.1、功能分析App功能在第一个Activity输入消息点击第一个Activity的发送按钮发送消息到第二个Act
- 前两天朋友问我,有没有使用过StackExchange.Redis,问我要个封装类,由于之前都是使用ServiceStack.Redis,由
- 下载maven 解压路径: 打开环境变量:右键此电脑-属性-高级系统设置-高级-环境变量添加以下系统变量:测试:win+
- SharedPreferences介绍:SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置
- 在我们实际开发项目中,经常会遇到一些常量的配置,比如url,暂时不会改变的字段参数,这个时候我们最好是不要直接写死在代码里的,因为这样编写的
- 最近几年玩得最疯狂的应该是发红包了,尤其是过年的时候特别受欢迎,下面写了红包的随机算法,其实挺简单的,仅是提供一种思路,希望可以给大家一些启
- http://mp.baomidou.com/#/?id=%e7%ae%80%e4%bb%8b 这个是mybatisplus的官方文档,上面
- 前言 前一段时间得闲的时候优化了一下我之前的轮子[DotNetCoreRpc]小框架,其中主要
- 大致流程客户端根据远程服务的地址,客户端发送请求至服务端,服务端解析信息并找到对应的实现类,进行方法调用,之后将调用结果原路返回,客户端解析
- 1.性能考虑,优先选择数组数组在项目开发当中使用的频率是越来越少,特别是在业务为主的开发当中,首先数组没有List,Set等集合提供的诸多方
- 覆盖类成员:通过new关键字修饰虚函数表示覆盖该虚函数。一个虚函数被覆盖后,任何父类变量都不能访问该虚函数的具体实现。public virt
- 该系统分为前台和后台,前台可以自主注册,后台管理员角色,除基础脚手架外,实现的功能有:后台管理员功能有:商品分类管理、商品管理、套餐管理、新
- Javaweb分页技术实现分页技术就是通过SQL语句(如下)来获取数据,具体实现看下面代码//分页查询语句select * from 表名
- 开发中有时候需要自己封装分页排序时,List如何对某一属性排序呢,分享一个小实例,大家共勉,希望能对大家有用,请多多指教。1.Student
- 前言 分享到微信朋友圈的功能早已经有了,但微信登录推出并不久,文档写的也并不是很清楚,这里记录分享一下。 正文 
- 一、Java语言本身也是多线程,回顾Java创建线程方式如下:1、继承Thread类,(Thread类实现Runnable接口),来个类图加
- 本文实例讲述了C#基于OLEDB获取Excel文件表结构信息的方法。分享给大家供大家参考,具体如下:这个问题来自论坛提问,同理可以获得acc
- 背景:我们在开发的过程中可能需要随机生成一个ID,例如数据库中的某个ID有时候也要对其进行校验。UUID:UUID,是Universally