Spring中IOC和AOP的深入讲解

 更新时间:2018年12月28日 08:42:24   作者:余同学的开发之路   我要评论

这篇文章主要给大家介绍了关于Spring中IOC和AOP的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

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 就是一个发车站,负责维护汽车对象和依赖对象汽车上的人,车就是目标对象,而我们要生成的代理对象就是通过收费站的汽车。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • Java 比较字符串实例详解

    Java 比较字符串实例详解

    这篇文章主要介绍了 Java 比较字符串实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • 基于HttpServletRequest 相关常用方法的应用

    基于HttpServletRequest 相关常用方法的应用

    本篇文章小编为大家介绍,基于HttpServletRequest 相关常用方法的应用,需要的朋友参考下
    2013-04-04
  • JAVA Map架构和API介绍

    JAVA Map架构和API介绍

    JAVA Map架构和API介绍:Map、Map.Entry、AbstractMap、SortedMap、 NavigableMap、Dictionary。
    2013-11-11
  • Struts2中ognl遍历数组,list和map方法详解

    Struts2中ognl遍历数组,list和map方法详解

    这篇文章主要介绍了Struts2中ognl遍历数组,list和map方法详解,需要的朋友可以参考下。
    2017-09-09
  • java中TreeMap排序的示例代码

    java中TreeMap排序的示例代码

    本篇文章主要介绍了java中TreeMap排序的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 详解springmvc拦截器拦截静态资源

    详解springmvc拦截器拦截静态资源

    本篇文章主要介绍了详解springmvc拦截器拦截静态资源,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-01-01
  • java获取注册ip实例

    java获取注册ip实例

    本文分享了java获取注册ip实例代码,代码简洁,具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • java中Properties文件加载和使用方法

    java中Properties文件加载和使用方法

    这篇文章主要为大家详细介绍了java中Properties文件加载和使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Java递归算法详解(动力节点整理)

    Java递归算法详解(动力节点整理)

    Java递归算法是基于Java语言实现的递归算法。递归算法对解决一大类问题很有效,它可以使算法简洁和易于理解。接下来通过本文给大家介绍Java递归算法相关知识,感兴趣的朋友一起学习吧
    2017-03-03
  • Android、iOS和Java通用的AES128加密解密示例代码

    Android、iOS和Java通用的AES128加密解密示例代码

    现在很多App在与服务器接口的请求和响应过程中,为了安全都会涉及到加密和解密的问题,如果不加的话就会是明文的,即使加了GZIP也可以被直接解压成明文。如果同时有Android和IOS的App的话、必须要保证加密和解密的算法一致、不然后台没法处理,下面通过这篇文章学习下。
    2016-11-11

最新评论