在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现。

一、采用Annotation方式

首先引入jar包:aspectjrt.jar && aspectweaver.jar

applicationContext配置文件:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 启用AspectJ对Annotation的支持 -->
<span style="color:#ff0000;"><aop:aspectj-autoproxy/></span> <bean id="user" class="com.angel.spring.User"/> <bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler"/> </beans>
</span>

接口和实现类省略

代理拦截类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; @Aspect
public class SuccessfulHandler { /**
* 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数
* 该方法就是一个标识,不进行调用
*/
@Pointcut("execution(* add*(..))")
private void addAddMethod(){}; /**
* 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
//@Before("addAddMethod()")
@After("addAddMethod()")
private void checkSecurity() {
System.out.println("-------Angel,方法执行成功!-------");
}
}
</span>

通过以上的配置,就可以实现对于方法调用的拦截。我们使用的注解有@Aspect,标记此类是一个横切面的插入类(拦截类),然后使用@Pointcut,标记我们的拦截方法需要作用于那些地方,最后使用@Before或者@After标记我们的拦截方法是作用于被调用方法前或者后。

但是,通过注解的方式,我们就需要为每个方法都添加注解,如果要修改的话,还得逐一修改,这样子,虽然同样轻便,但是如果有一个地方统一配置AOP的话,那就会更为简便,接下来,我们看第二种实现方式:采用配置方式

二、采用配置方式

applicationContext的配置:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 启用AspectJ对Annotation的支持 -->
<!-- <aop:aspectj-autoproxy/> --> <bean id="user" class="com.angel.spring.User" /> <bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler" /> <aop:config>
<aop:aspect id="IsSuccessfulAspect" ref="successfulHandler">
<!-- com.bjpowernode.spring包下所有的类所有的方法
<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/> -->
<!-- com.bjpowernode.spring包下所有的类的以add和del开头的方法-->
<aop:pointcut id="addAddMethod" expression="execution(* com.angel.spring.*.add*(..)) || execution(* com.angel.spring.*.del*(..))" />
<aop:before method="checkSecurity" pointcut-ref="addAddMethod" />
</aop:aspect>
</aop:config> </beans>
</span>

拦截类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

import org.aspectj.lang.JoinPoint;

public class SuccessfulHandler {

	private void checkSecurity(JoinPoint joinPoint) {

		System.out.println("-------Angel,方法执行成功!-------");
}
}</span>

经过这样的配置就可以实现方法的拦截了,但有时候,我们不仅需要拦截方法名称,我们还需要知道,在执行这个方法的时候,用户到底传递了什么样的参数,那么,我们需要在拦截类采用Advice中添加一个JoinPoint参数,取得客户端调用的方法名称及参数值,如:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

import org.aspectj.lang.JoinPoint;

public class SuccessfulHandler {

	private void checkSecurity(JoinPoint joinPoint) {
for (int i=0; i<joinPoint.getArgs().length; i++) {
System.out.println(joinPoint.getArgs()[i]);
}
System.out.println(joinPoint.getSignature().getName());
System.out.println("-------Angel,方法执行成功!-------");
}
}</span>

三、采用CGLIB代理

以上的例子,我们都是采用JDK的代理实现的AOP,JDK的动态代理是代理的接口,如果有些类并没有实现接口,那么我们将不得不采用另外一种代理方式:CGLIB动态代理。如:

首先,引入支撑CGLIB的jar包cglib-nodep.jar

其次,在applicationContext配置文件中,强制开启CGLIB代理:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><!-- 强制使用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" /></span>

区别:User类不再实现IUser接口,而是一个单独的类,代理成功!

四、总结

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

对于AOP的总结,到此结束,接下来总结事务的知识点。PS:深刻感觉,之前对于AOP是被吓退了!

【spring 5】AOP:spring中对于AOP的的实现的更多相关文章

  1. Spring框架中的aop操作之二 通过配置文件实现增强

    aop表达式写法 配置文件代码: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...

  2. 【Java】Spring之面向方面编程(AOP)(五)

    面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP).OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面.方面实现了跨越多种类型和对象的关注点(例如事务管理)的 ...

  3. Spring Aop(一)——Aop简介

    转发地址:https://www.iteye.com/blog/elim-2394629 1 Aop简介 AOP的全称是Aspect Oriented Programming,翻译成中文是面向切面编程 ...

  4. Spring基础(二)_面向切面(AOP)

    面向切面编程 面向切面编程[AOP,Aspect Oriented Programming]:通过预编译方式和运行期间动态代理实现程序功能的统一维护的技术.AOP 是 Spring 框架中的一个重要内 ...

  5. Spring学习笔记-面向切面(AOP)-04

    什么是面向切面编程 先大概了解一下部分术语 横切关注点:软件开发中,散布于多出的功能称为横切关注点(cross-cutting concern),简单的可以描述为可以影响应用多处的功能,比如日志.安全 ...

  6. 转-Spring Framework中的AOP之around通知

    Spring Framework中的AOP之around通知 http://blog.csdn.net/xiaoliang_xie/article/details/7049183 标签: spring ...

  7. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  8. Spring中的AOP

    什么是AOP? (以下内容来自百度百科) 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种 ...

  9. Spring中的AOP开发

    1.代理模式 找个人将你原本想做的事情给做了. 三个部分组成: 抽象主题角色:真实主题和代理主题的共同接口. 真实主题角色:定义了代理角色所代表的真实对象. 代理主题角色:含有对真实主题角色的引用.代 ...

随机推荐

  1. [物理学与PDEs]第1章 电动力学

    [物理学与PDEs]第1章第1节 引言 [物理学与PDEs]第1章第2节 预备知识 2.1 Coulomb 定律, 静电场的散度与旋度 [物理学与PDEs]第1章第2节 预备知识 2.2 Ampere ...

  2. [物理学与PDEs]第2章习题参考解答

    [物理学与PDEs]第2章习题1 无旋时的 Euler 方程 [物理学与PDEs]第2章习题2 质量力有势时的能量方程 [物理学与PDEs]第2章习题3 Laplace 方程的 Neumann 问题 ...

  3. bug_ _java.lang.RuntimeException: Unable to start activity ComponentInfo{包名/类名}

      写这篇博文,我顶着很大的压力,贴出来会引来网友的一片鄙视,不贴我又觉得对不起Android SDK研发团队. 本着对全世界Android无产者负责的态度,今天不得不指出Android编译时隐藏的很 ...

  4. purple-accessData

    ylbtech-class:purple-accessData A, 返回顶部 1,送货时间 #region 送货时间 /// <summary> /// 送货时间 /// </su ...

  5. JAVA 数组实例-求学生平均成绩,与计算数组的长度

    实例: 知识点:数组名.length是计算数组的长度 import java.util.*; //求学生平均分成绩 public class Test{ public static void main ...

  6. Fatal error: Class 'GearmanClient' not found解决方法

    产生原因: 没有安装PHP的gearman扩展 解决方法:1.  打开:http://pecl.php.net/package/gearman2.  wget  http://pecl.php.net ...

  7. CentOS 6.5 更新163源(转载)

    From:http://www.cnblogs.com/buffer/p/3426908.html 众所周知,Centos 有个很方便的软件安装工具  yum,但是默认安装完centos,系统里使用的 ...

  8. Linux设置服务自启动(转载)

    From:http://www.cnblogs.com/nerxious/archive/2013/01/18/2866548.html 有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统 ...

  9. Django 应用 Buildbot

    Django作者之一 JACOB KAPLAN 所写的buildbot应用在Django系统. 全文总共分为两个部分 1,http://jacobian.org/writing/ci-is-hard/ ...

  10. Spring配置项<context:annotation-config/>说明

    配置applicationContext.xml时经常会看到: <context:annotation-config/> 它的作用是隐式地向Spring容器注册AutowiredAnnot ...