如何理解Spring的AOP?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解Spring的AOP?相关的知识,希望对你有一定的参考价值。

参考技术A

Spring的AOP面向切面编程,就是横向的,比如程序运行时都要建日志,相当于SQL的触发器。

Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。

Spring特点:

1、方便解耦,简化开发

通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

2、AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

3、声明式事务的支持

在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

4、方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5、方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

6、降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

7、Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。

深入理解AOP-代理的秘密

学过Spring框架的人都知道有AOP,面向切面编程,也理解切面[Aspect=Advice+PointCut]的公式,知道如何配置、使用,但是,这几个概念的核心原理你未必都懂,今天我们从代理的底层代码出发,来看看Spring中的AOP是怎么基于JDK的代理和CGLIB的代理来实现动态“织入”切面的能力的。


首先,我们来看一个简单的案例:

定义接口如下:

/*******

 * 业务接口

 */

public interface Calculate{

  int divide(int a, int b);

}

实现类如下:

/***************

 * 业务实现类

 */

public class CalculateImpl implement Calculate{

  @Override

  int divide(int a, int b) {

    int result = a / b;

    return result;

  }

}

现在,请思考一下?

如何在不改变业务实现类的代码情况下,给它添加日志功能,要求这个日志要在业务方法调用之前、之后、返回后或是在出现异常时都要记录下来,如何做到?


这是一个典型的AOP业务场景,在不改变原有类的情况下,动态添加新的功能,也就是日志,我们给出两种方案:


方案一:

根据接口的扩展原则,我们可以扩展出另一个类来实现Calculate 接口,并在此类中添加新的功能,把日志加上,如下:

/***************

 * 业务实现类2

 */

public class CalculateImpl2 implement Calculate{

  @Override

  int divide(int a, int b) {

    //记录日志

    try {

        int result = a / b;

         //记录日志

        return result;

    } catch (Exception e) {

        //记录日志

    } finally {

        //记录日志

    }

  }

}

然后,我们使用这个新类来调用业务方法,在不改变原来的类的基础上,确实也做到了添加新功能,但这种方式的缺点是“硬编码”,每加一种切面功能时,都要扩展出一个新类,当扩展的功能要交叉时,管理上很麻烦,所以,这种方式是一种静态的代理方式,也叫扩展,不是我们今天的主题,但是,在软件的架构上,这种思想还是很有用的,这里提一下。


方案二:【重点】

也就是采用动态代理,我们无需创建一个新的业务类来实现业务接口,从而在实现的业务方法中添加新功能,而是利用动态代理的能力,由JVM帮助我们在原有实现类的基础上,动态地“织入”我们的功能(这里是日志),听上去非常高大上,有没有! 那它是如何做到的呢?


Spring框架中使用两种方式来实现动态代理,分别是:


方式一:基于JDK的动态代理

此方式要求被代理的对象一定要实现一个或多个接口【Spring默认采用此方式】


方式二:基于CGLIB的动态代理

此方式对被代理对象无任何要求,功能强大【如果没有接口时,Spring采用此方式】




叶老师技术博客:http://www.teacherye.com 


以上是关于如何理解Spring的AOP?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解Spring中的IOC和AOP

如何简单理解spring aop和事务

怎么样理解spring ioc与aop

如何理解spring中的切面和过滤

spring的ioc和aop都是啥??

#yyds干货盘点# Spring核心之面向切面编程(AOP)