【SSH快速进阶】——Spring AOP原理及其实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/52046439

  上篇文章简单总结了一下静态代理以及JDK和Cglib两种方式实现的动态代理。由此也延伸出了一个重要的编程思想:AOP。

AOP原理


  AOP(Aspect Oriented Programming):面向切面编程。利用AOP可以对业务逻辑中的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  AOP主要面向独立的服务,跟业务没有任何关系,通常会遍布在系统的任何角落,如系统的日志、权限检查等服务。

  在Spring 的AOP中,有如下概念:

  上图中,每部分的解释如下:

Cross cutting concern   横切性关注点,一种独立服务,它会遍布在系统的处理流程中(比如日志服务、权限检查等)

Aspect   对横切性关注点的模块化(如果横切服务要运行,就必须放在一个类里,可以把它看做是Aspect)

Advice   对横切性关注点的具体实现(包括before、after、throwing等),比如在用户操作之前检查用户权限(before);在生成订单之后记录日志(after);在某个方法抛异常之后进行异常处理(throwing)等。

Pointcut   它定义了Advice应用到哪些JoinPoint上(即应用到哪些类的那些方法上),对Spring来说是方法调用。动态代理中,会把服务加到所有方法上,但在实际应用中可能不会把服务加到所有的方法上,AOP中就可以定义切入点,即进行过滤,AOP服务加到哪些方法上。

JoinPoint   Advice在应用程序上执行的点或时机(比如在类A的a()方法执行之前执行某个操作,或修改类A的b属性时触发某个操作),Spring只支持方法的JoinPoint,Aspecj可以支持可以使属性修改的JoinPoint。Advice执行在JoinPoint上。

Spring AOP实现


  Spring AOP实现步骤大致如下:

  1、Spring jar包的依赖

SPRING_HOME/dist/spring.jar
SPRING_HOME/lib/log4j/log4j-1.2.14.jar
SPRING_HOME/lib/jakarta-commons/commons-logging.jar
SPRING_HOME/lib/aspectj/*.jar

  2、首先在Spring配置文件中启用Aspect对Annotation的支持:

<aop:aspectj-autoproxy/>

  3、定义Aspect

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Before;

@Aspect
public class SecurityHandler {

    @Pointcut("execution(* add*(..))")
    private void addMethod(){}

    /**
     * 在【* add*(..)】匹配的方法执行之前执行
     */
    @Before("addMethod()")
    private void checkSecurityBeforeAdd(){
        System.out.println("----Before Add:checkSecurity-----");
    }

    /**
     * 在【* add*(..)】匹配的方法执行之后执行
     */
    @After("addMethod()")
    private void addLogAfterAdd(){
        System.out.println("----After Add:addLog-----");
    }

    /**
     * 在【* add*(..)】匹配的方法执行报异常之后执行
     */
    @AfterThrowing("addMethod()")
    private void addLogAfterThrowing(){
        System.out.println("----After Throwing:Throwing-----");
    }

}

  上面的SecurityHandler 类就是权限检查的服务,可以定义在某些方法执行之前、某些方法执行之后等时间点切入该服务。

@Aspect   在SecurityHandler类上打上@Aspect注解,就说明它是上面图中的Cross cutting concern经过封装后的模块了,Spring容器加载该类的时候会把它里面定义的所有横切性服务(Advice)都应用到相应的方法(Pointcut)上。

@Pointcut   上面例子中@Pointcut标记的方法名称是addMethod,且该方法是一个没有参数和返回值的空方法,该方法可以看做就是一种标记,不进行调用。("execution(* add*(..))") 定义的就是过滤要添加横切性服务的一些方法的条件。具体解释是:第一个*匹配所有类型返回值的方法;第二个*匹配所有方法头带“add”的方法;..表示匹配有参数和无参数的方法都满足条件。更多过滤条件请见Spring Framework开发手册,小编也特意为大家截了张图:点这里看大图

@Before、@After、@Throwing   上面例子中其余三种Advice:@Before、@After、@Throwing,大家看注释应该也就看明白了,这是三个执行时机,分别会在目标方法执行前、执行后、报异常后执行。需要注意的是注解后面括号里的内容必须要是@Pointcut定义的方法名称,说明这三个时机执行的Advice都为该方法服务。

  3、客户端调用AOP 服务

public static void main(String[] args) {
    String[] configurations=new String[]{"applicationContext-bean.xml"};
    beanFactory=new ClassPathXmlApplicationContext(configurations);

    UserManager userManager=(UserManager)beanFactory.getBean("userManager");
    userManager.addUser(new User("Danny","12456")); 
}

  以上是用注解的形式来配置的AOP服务,当然也可以用配置文件来配,用配置文件配的时候,上面第2步骤可以省略。

  代理类:

public class SecurityHandler{
    private void checkSecurity(){
        System.out.println("----checkSecurity-----");
    }
}

  配置文件:

<bean id="securityHandler" class="com.danny.spring.SecurityHandler"/>

<aop:config>
    <aop:aspect id="securityAspect" ref="securityHandler">
        <aop:pointcut id="addMethod" expression="execution(* add*(..))"/>
        <aop:before method="checkSecurity" pointcut-ref="addMethod"/>
    </aop:aspect>
</aop:config>

  如果把这种思想运用到项目中,与业务不相干的服务都用AOP切入,极大地减小了服务与业务的耦合,提升了开发效率。


【 转载请注明出处——胡玉洋《【SSH快速进阶】——Spring AOP原理及其实现》】

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏余林丰

Spring AOP高级——源码实现(2)Spring AOP中通知器(Advisor)与切面(Aspect)

本文例子完整源码地址   之所以还未正式进入Spring AOP的源码,是因为我在阅读Spring AOP生成代理对象时遇到了一点小麻烦让我不得不暂时停止,转而...

2558
来自专栏Java帮帮-微信公众号-技术文章全总结

Java开发Spring笔记第二天

今日内容 AOP的概述 AOP 的底层实现 Spring 的AOP 使用AspectJ 实现AOP Spring JdbcTemplate 使用 1.2 Spr...

36014
来自专栏禁心尽力

总结切面编程AOP的注解式开发和XML式开发

       有段日子没有总结东西了,因为最近确实有点忙,一直在忙于hadoop集群的搭建,磕磕碰碰现在勉强算是能呼吸了,因为这都是在自己的PC上,资源确实有点...

25510
来自专栏Java帮帮-微信公众号-技术文章全总结

SpringAop实现原理

SpringAop实现原理 什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Orien...

4684
来自专栏cs

spring的AOP知识点2.0

一AOP相关概念 Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.

1445
来自专栏菩提树下的杨过

redis 学习笔记(5)-Spring与Jedis的集成

首先不得不服Spring这个宇宙无敌的开源框架,几乎整合了所有流行的其它框架,http://projects.spring.io/spring-data/ 从这...

2527
来自专栏Java帮帮-微信公众号-技术文章全总结

Java多线程详解5【面试+工作】

Java多线程详解【面试+工作】 Java线程:新特征-信号量 Java的信号量实际上是一个功能完毕的计数器,对控制一定资源的消费与回收有着很重要的意义,信号量...

42010
来自专栏智能算法

女程序员做了个梦,众网友的神回复

原出处来自豆瓣网:《一个女程序员twitter上发了一条tweet》 链接:http://www.douban.com/group/topic/14168111...

34213
来自专栏coolblog.xyz技术专栏

Spring IOC 容器源码分析 - 余下的初始化工作

本篇文章是“Spring IOC 容器源码分析”系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的...

991
来自专栏中国Android研究院

面向切面编程(AOP)在Android中的应用

AOP,字面翻译为面向切面编程。它是一种编程思想,不是什么新技术。可以这么理解,在Android开发过程中,我们经常会在我们的具体业务代码中加入全局性、系统性的...

4705

扫码关注云+社区

领取腾讯云代金券