AspectJ:(Java社区里最完整最流行的AOP框架)

spring自身也有一套AOP框架,但相比较于AspectJ,更推荐AspectJ

在Spring2.0以上版本中,可以使用基于AspectJ注解或基于XML配置的AOP。

AspectJ最强大的地方在于他的切入点表达式:

语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

  修饰符,一般省略

    public 公共方法

               * 任意

  返回值,不能省略

    void 返回没有值

    String 返回值字符串

    * 任意

  包

    com.zby.service  固定包

    com.zby.oa.*.service oa包下面子包 (例如:com.zby.oa.flow.service)

    com.zby.oa..   oa包下面的所有子包(含自己)

    com.zby.oa.*.service.. oa包下面任意子包,固定目录service,service目录任意包

  类

    UserServiceImpl 指定类

    *Impl 以Impl结尾

    User* 以User开头

    * 任意

  方法名,不能省略

    addUser 固定方法

    add* 以add开头

    *Do 以Do结尾

    * 任意

  (参数)

    () 无参

    (int) 一个整型

    (int ,int) 两个

    (..) 参数任意

  throws ,可省略,一般不写

AspectJ支持5种类型的通知注解:

before:前置通知(应用:各种校验)
   在方法执行前执行,如果通知抛出异常,阻止方法运行

afterReturning:后置通知(应用:常规数据处理)
           方法正常返回后执行,如果方法中抛出异常,通知无法执行,必须在方法执行后才执行,所以可以获得方法的返回值。

around:环绕通知(应用:十分强大,可以做任何事情)
           方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法

afterThrowing:抛出异常通知(应用:包装异常信息)
           方法抛出异常后执行,如果方法没有抛出异常,无法执行

after:最终通知(应用:清理现场)
      方法执行完毕后执行,无论方法中是否出现异常

当然,最重要也最常用的还是环绕通知,因为环绕通知必须手动执行目标方法,所以,可以代替其他几个通知

项目结构图:

一:maven项目依赖

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>demo</groupId>
  5. <artifactId>demo</artifactId>
  6. <version>0.0.1-SNAPSHOT</version>
  7. <packaging>war</packaging>
  8. <name>demo</name>
  9. <description>demo</description>
  10. <dependencies>
  11. <dependency>
  12. <groupId>org.springframework</groupId>
  13. <artifactId>spring-context</artifactId>
  14. <version>4.3.8.RELEASE</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework</groupId>
  18. <artifactId>spring-aop</artifactId>
  19. <version>4.3.8.RELEASE</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework</groupId>
  23. <artifactId>spring-aspects</artifactId>
  24. <version>4.3.8.RELEASE</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework</groupId>
  28. <artifactId>spring-test</artifactId>
  29. <version>4.3.8.RELEASE</version>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.aspectj</groupId>
  33. <artifactId>aspectjweaver</artifactId>
  34. <version>1.8.10</version>
  35. </dependency>
  36. </dependencies>
  37. </project>

二:声明切点

I.切面首先是一个IOC中的bean,即加入@Component注释

  1. package com.debo.aspect.service;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class AspectService {
  5. //添加
  6. public void add() {
  7. }
  8. //修改
  9. public void update() {
  10. }
  11. //删除
  12. public void delete() {
  13. }
  14. }

三:声明切面

I.切面首先是一个IOC中的bean,即加入@Component注释
II.切面还需要加入@Aspect

  1. package com.debo.aspect.service;
  2. import java.lang.reflect.Method;
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.After;
  6. import org.aspectj.lang.annotation.AfterReturning;
  7. import org.aspectj.lang.annotation.AfterThrowing;
  8. import org.aspectj.lang.annotation.Around;
  9. import org.aspectj.lang.annotation.Aspect;
  10. import org.aspectj.lang.annotation.Before;
  11. import org.aspectj.lang.annotation.Pointcut;
  12. import org.springframework.stereotype.Component;
  13. @Aspect
  14. @Component
  15. public class MyAspectJ {
  16. // 多个方法需要使用这个切入点表达式,定义为一个公用的
  17. @Pointcut("execution(* com.debo.*.service.*.add*(..))")
  18. public void addCell() {
  19. }
  20. @Before("execution(* com.debo.*.service.*.update*(..))")
  21. public void updateCell() {
  22. System.out.println("更新的前置通知");
  23. }
  24. @After("execution(* com.debo.*.service.*.delete*(..))")
  25. public void deleteCell() {
  26. System.out.println("删除的最终通知");
  27. }
  28. @AfterReturning(value = "addCell()", returning = "ret")
  29. public void returnAdd(JoinPoint joinPoint, Object ret) {
  30. System.out.println("添加的后置通知 : " + joinPoint.getSignature().getName());
  31. }
  32. @Around("addCell()")
  33. public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
  34. System.out.println("环绕通知执行方法前");
  35. // 手动执行目标方法
  36. Object obj = joinPoint.proceed();
  37. System.out.println("环绕通知执行方法后");
  38. return obj;
  39. }
  40. @AfterThrowing(value = "addCell()", throwing = "e")
  41. public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
  42. System.out.println("抛出异常通知 : " + e.getMessage());
  43. }
  44. }

四:xml配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"<span style="color:#ff0000;"> xmlns:aop="http://www.springframework.org/schema/aop"</span>
  5. <span style="color:#ff0000;">xmlns:context="http://www.springframework.org/schema/context"</span>
  6. xmlns:mvc="http://www.springframework.org/schema/mvc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
  11. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
  12. <!-- 注解扫描 -->
  13. <context:component-scan base-package="com.debo.*.service" />
  14. <!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
  15. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  16. </beans>

五:测试

  1. package com.debo.aspect.service;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class Test {
  5. public static void main(String[] args) {
  6. // 1.创建Spring的IOC容器
  7. ApplicationContext ctx = new ClassPathXmlApplicationContext(
  8. "applicationContext.xml");
  9. // 2.从IOC容器中获取bean的实例
  10. AspectService aspectService = ctx.getBean(AspectService.class);
  11. aspectService.add();
  12. aspectService.update();
  13. aspectService.delete();
  14. }
  15. }

原文链接:http://blog.csdn.net/qq_37936542/article/details/79555762

spring+aspectJ的实现的更多相关文章

  1. Spring4.0学习笔记(11) —— Spring AspectJ 的五种通知

    Spring AspectJ 一.基于注解的方式配置通知 1.额外引入的jar包: a) com.springsource.org.aopalliance-1.0.0.jar b) com.sprin ...

  2. Spring AspectJ AOP 完整示例

    http://outofmemory.cn/java/spring/AOP/aop-aspectj-example-before-after-AfterReturning-afterThrowing- ...

  3. Spring(十二)--Spring AspectJ

    Spring AspectJ AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. As ...

  4. Spring AspectJ基于注解的AOP实现

    对于AOP这种编程思想,很多框架都进行了实现.Spring就是其中之一,可以完成面向切面编程.然而,AspectJ也实现了AOP的功能,且实现方式更为简捷,使用更加方便,而且还支持注解式开发.所以,S ...

  5. Spring @AspectJ 实现AOP 入门例子(转)

    AOP的作用这里就不再作说明了,下面开始讲解一个很简单的入门级例子. 引用一个猴子偷桃,守护者守护果园抓住猴子的小情节. 1.猴子偷桃类(普通类): package com.samter.common ...

  6. spring AspectJ的Execution表达式

    Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式  execu ...

  7. spring AspectJ的Execution表达式说明

    Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execut ...

  8. Spring AspectJ的Execution表达式-备忘笔记

    Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式  execu ...

  9. Spring AspectJ切入点语法详解

    1.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指 ...

  10. spring AspectJ切入点语法详解 记录以便查阅

    AspectJ切入点语法详解 6.5.1  Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spri ...

随机推荐

  1. java sort

    MyString mySs[]=new MyString[result.length];//创建自定义排序的数组 for (int i = 0; i < result.length; i++) ...

  2. Python3的取余操作

    https://blog.csdn.net/u014647208/article/details/53368244 取余代码: 输入以下代码: >>>10%2 >>> ...

  3. python内存增长问题

    如果你的程序没有调用什么特殊的库, 只是用了很平常的库, 而且使再循环很多的情况下, 那么建议你把循环里的程序拆出来,写成一子函数,循环子函数. 如下面格式: for   (循环) 子函数 这样程序每 ...

  4. Fiddler代理配置

     1.下载安装软件Fiddler 2.Fiddler设置HTTPS代理(如果代理的是https请求的需要操作这一步) 打开Fiddler,菜单栏:Tools -> Fiddler Options ...

  5. 洛谷—— P1062 数列

    https://www.luogu.org/problem/show?pid=1062#sub 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增 ...

  6. JS学习笔记 - 面向对象 - 原型

    <script> var arr1 = new Array(12, 55, 34, 78, 676); var arr2 = new Array(12, 33, 1) Array.prot ...

  7. spring接收对象数组实例

    JS var param= new Array(); var one= new Object; one.id = '1'; one.name= 'simba1'; param.push(one); v ...

  8. Android Studio查看android源码

    Android Studio的默认版本在/Applications/Android Studio.app/Contents/info.plist中设置,默认没有1.8.如下: <key>J ...

  9. 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析

    1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...

  10. Caffe 安装 Ubuntu14.04+CUDA7.0/7.5(亲测有效)

    自己安装Caffe的过程中,参考了很多资料,但由于版本或者其他原因,安装过程中总是遇到这样或者那样的问题,因此留做记录,方便之后查看,也希望对遇到相似麻烦的朋友们提供帮助.  下面我们开始安装吧: 硬 ...