spring+aspectJ的实现

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.   
  3. import org.springframework.stereotype.Component;  
  4.   
  5. @Component  
  6. public class AspectService {  
  7.   
  8.     //添加  
  9.     public void add() {  
  10.   
  11.     }  
  12.   
  13.     //修改  
  14.     public void update() {  
  15.   
  16.     }  
  17.   
  18.     //删除  
  19.     public void delete() {  
  20.   
  21.     }  
  22.   
  23. }  


三:声明切面

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

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


四: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.     <!-- 注解扫描 -->  
  14.     <context:component-scan base-package="com.debo.*.service" />  
  15.   
  16.     <!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->  
  17.     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>  
  18.       
  19. </beans>  


五:测试

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

原文链接:http://blog.csdn.net/qq_37936542/article/details/79555762
posted @ 2018-03-20 09:59  前端视听  阅读(129)  评论(0编辑  收藏  举报