zoukankan      html  css  js  c++  java
  • [原创]java WEB学习笔记108:Spring学习---基于配置文件的形式实现AOP

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

    内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

    本人互联网技术爱好者,互联网技术发烧友

    微博:伊直都在0221

    QQ:951226918

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.用基于 XML 的配置声明切面

      1) 除了使用 AspectJ 注解声明切面, Spring 也支持在 Bean 配置文件中声明切面. 这种声明是通过 aop schema 中的 XML 元素完成的.

      2) 正常情况下, 基于注解的声明要优先于基于 XML 的声明. 通过 AspectJ 注解, 切面可以与 AspectJ 兼容, 而基于 XML 的配置则是 Spring 专有的. 由于 AspectJ 得到越来越多的 AOP 框架支持, 所以以注解风格编写的切面将会有更多重用的机会.

       

      基于 XML ---- 声明切面

      3) 当使用 XML 声明切面时, 需要在 <beans> 根元素中导入 aop Schema

      4) 在 Bean 配置文件中, 所有的 Spring AOP 配置都必须定义在 <aop:config> 元素内部. 对于每个切面而言, 都要创建一个 <aop:aspect> 元素来为具体的切面实现引用后端 Bean 实例.

      5) 切面 Bean 必须有一个标示符, 供 <aop:aspect> 元素引用

     

      

      基于 XML ---- 声明切入点

      6) 切入点使用 <aop:pointcut> 元素声明

      7) 切入点必须定义在 <aop:aspect> 元素下, 或者直接定义在 <aop:config> 元素下:  定义在 <aop:aspect> 元素下: 只对当前切面有效 定义在 <aop:config> 元素下: 对所有切面都有效

      8)  基于 XML 的 AOP 配置不允许在切入点表达式中用名称引用其他切入点.

     

      

      基于 XML ---- 声明通知

      9) 在 aop Schema 中, 每种通知类型都对应一个特定的 XML 元素.

      10)通知元素需要使用 <pointcut-ref> 来引用切入点, 或用 <pointcut> 直接嵌入切入点表达式. method 属性指定切面类中通知方法的名称.

    2.关于配置的核心代码

      aop-xml.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:aop="http://www.springframework.org/schema/aop"
     5     xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
     6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     7 
     8 
     9     <!-- 配置bean -->
    10     <bean id="arithmeticCaculator" class="com.jason.spring.aop.impl.ArithmeticCaculatorImpl"> </bean>
    11     
    12     <!-- 配置切面的bean -->
    13     <bean id="loggingAspect" class="com.jason.spring.aop.impl.LoggingAspect"></bean>
    14     <bean id="validateArgs" class="com.jason.spring.aop.impl.ValidateArgs"></bean>
    15     
    16     <!-- 配置aop -->
    17     <aop:config>
    18         <!-- 配置切点表达式 -->
    19         <aop:pointcut expression="execution(* com.jason.spring.aop.impl.ArithmeticCaculator.*(..))" id="pointcut"/>
    20     
    21         <!-- 配置切面和通知 -->
    22         <aop:aspect ref="loggingAspect" order="2">
    23             <aop:before method="beforeMethod" pointcut-ref="pointcut"/>
    24         </aop:aspect>
    25         <aop:aspect ref="validateArgs" order="1">
    26             <aop:before method="validateArgs" pointcut-ref="pointcut"/>
    27         </aop:aspect>
    28         
    29     </aop:config>
    30     
    31 </beans>

      

    3.其他代码

      

    ArithmeticCaculator.java
     1 package com.jason.spring.aop.impl;
     2 
     3 public interface ArithmeticCaculator {
     4     
     5     int add(int i, int j);
     6     int sub(int i, int j);
     7     
     8     int mul(int i, int j);
     9     int div(int i, int j);
    10     
    11 }

    ArithmeticCaculatorImpl.java
     1 package com.jason.spring.aop.impl;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 
     6 //@Component
     7 
     8 public class ArithmeticCaculatorImpl implements ArithmeticCaculator {
     9 
    10     @Override
    11     public int add(int i, int j) {
    12         int result = i + j;
    13         return result;
    14     }
    15 
    16     @Override
    17     public int sub(int i, int j) {
    18         int result = i - j;
    19         return result;
    20     }
    21 
    22     @Override
    23     public int mul(int i, int j) {
    24         int result = i * j;
    25         return result;
    26     }
    27 
    28     @Override
    29     public int div(int i, int j) {
    30         int result = i / j;
    31         return result;
    32     }
    33 
    34 }
    LoggingAspect.java
      1 package com.jason.spring.aop.impl;
      2 
      3 import java.util.Arrays;
      4 import java.util.List;
      5 
      6 import org.aspectj.lang.JoinPoint;
      7 import org.aspectj.lang.ProceedingJoinPoint;
      8 import org.aspectj.lang.annotation.After;
      9 import org.aspectj.lang.annotation.AfterReturning;
     10 import org.aspectj.lang.annotation.AfterThrowing;
     11 import org.aspectj.lang.annotation.Around;
     12 import org.aspectj.lang.annotation.Aspect;
     13 import org.aspectj.lang.annotation.Before;
     14 import org.aspectj.lang.annotation.Pointcut;
     15 import org.springframework.core.annotation.Order;
     16 import org.springframework.stereotype.Component;
     17 
     18 
     19 /*@Order(1)
     20 //把这个类声明为一个切面
     21 //1.需要将该类放入到IOC 容器中
     22 @Component
     23 //2.再声明为一个切面
     24 @Aspect*/
     25 public class LoggingAspect {
     26     
     27     /**
     28      * 
     29      * @Author:jason_zhangz@163.com
     30      * @Title: declareJointPointExpression 
     31      * @Time:2016年12月6日
     32      * @Description: 定义一个方法,用于声明切入点表达式。一般的,该方法不需要添加其他代码
     33      *
     34      */
     35     //@Pointcut("execution(* com.jason.spring.aop.impl.*.*(int, int))")
     36     public void declareJointPointExpression(){}
     37     
     38     
     39     //声明该方法是一个前置通知:在目标方法开始之前执行 哪些类,哪些方法
     40     //作用:@before 当调用目标方法,而目标方法与注解声明的方法相匹配的时候,aop框架会自动的为那个方法所在的类生成一个代理对象,在目标方法执行之前,执行注解的方法
     41     //支持通配符
     42     //@Before("execution(public int com.jason.spring.aop.impl.ArithmeticCaculatorImpl.*(int, int))")
     43     //@Before("declareJointPointExpression()")
     44     public void beforeMethod(JoinPoint joinPoint){
     45         String methodName = joinPoint.getSignature().getName();
     46         List<Object> args = Arrays.asList(joinPoint.getArgs());
     47         System.out.println("The method " + methodName + " begins " + args);
     48     }
     49     
     50     /**
     51      * 
     52      * @Author:jason_zhangz@163.com
     53      * @Title: afterMethod 
     54      * @Time:2016年12月1日
     55      * @Description:  在方法执行后执行的代码,无论该方法是否出现异常
     56      *
     57      * @param joinPoint
     58      */
     59     //@After("declareJointPointExpression()")
     60     public void afterMethod(JoinPoint joinPoint){
     61         String methodName = joinPoint.getSignature().getName();
     62         List<Object> args = Arrays.asList(joinPoint.getArgs());
     63         System.out.println("The method " + methodName + " end " + args);
     64     }
     65     
     66     /**
     67      * 
     68      * @Author:jason_zhangz@163.com
     69      * @Title: afterReturning 
     70      * @Time:2016年12月1日
     71      * @Description:  在方法正常结束后执行代码,放回通知是可以访问到方法的返回值
     72      *
     73      * @param joinPoint
     74      */
     75     //@AfterReturning( value="declareJointPointExpression()", returning="result")
     76     public void afterReturning(JoinPoint joinPoint ,Object result){
     77         String methodName = joinPoint.getSignature().getName();
     78         System.out.println("The method " + methodName + " end with " + result);
     79     }
     80     
     81     /**
     82      * 
     83      * @Author:jason_zhangz@163.com
     84      * @Title: afterThrowting 
     85      * @Time:2016年12月1日
     86      * @Description:  在目标方法出现异常时会执行代码,可以访问到异常对象,且,可以指定出现特定异常时执行通知代码
     87      *
     88      * @param joinPoint
     89      * @param ex
     90      */
     91     //@AfterThrowing(value="declareJointPointExpression()",throwing="ex")
     92     public void afterThrowting(JoinPoint joinPoint, Exception  ex){
     93         String methodName = joinPoint.getSignature().getName();
     94         System.out.println("The method " + methodName + " occurs exceptions " + ex);
     95     }
     96     
     97     /**
     98      * 
     99      * @Author:jason_zhangz@163.com
    100      * @Title: around 
    101      * @Time:2016年12月1日
    102      * @Description: 环绕通知需要携带 ProceedingJoinPoint 类型的参数
    103      *                    环绕通知 类似于  动态代理的全过程
    104      *                   ProceedingJoinPoint:可以决定是否执行目标方法
    105      *    环绕通知必须有返回值,返回值即为目标方法的返回值
    106      *    
    107      * @param proceedingJoinPoint
    108      */
    109     //@Around("declareJointPointExpression()")
    110     public Object around(ProceedingJoinPoint proceedingJoinPoint){
    111         
    112         Object result = null;
    113         String methodName = proceedingJoinPoint.getSignature().getName();
    114         
    115         //执行目标方法
    116         try {
    117             //前置通知
    118             System.out.println("The method " + methodName + "begin with" + Arrays.asList(proceedingJoinPoint.getArgs()));
    119             
    120             result = proceedingJoinPoint.proceed();
    121             
    122             //后置通知
    123             System.out.println("The method " + methodName + "end with" + result);
    124             
    125         } catch (Throwable e) {
    126             //异常通知
    127             System.out.println("The method occurs exception : " + e);
    128             throw new RuntimeException();
    129         }
    130             //后置通知
    131             
    132         System.out.println("The method " + methodName + "end with" + result);
    133         
    134         return result;
    135         
    136     }
    137     
    138     
    139 }
    ValidateArgs.java
     1 package com.jason.spring.aop.impl;
     2 
     3 import java.util.Arrays;
     4 
     5 import org.aspectj.lang.JoinPoint;
     6 import org.aspectj.lang.annotation.Aspect;
     7 import org.aspectj.lang.annotation.Before;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.core.annotation.Order;
    10 import org.springframework.stereotype.Component;
    11 
    12 /**
    13  * 
    14  * @ClassName:ValidateArgs
    15  * @Description:可以使用@Order 注解指定切面的优先级,值越小优先级越高
    16  * @author: jason_zhangz@163.com
    17  * @date:2016年12月6日下午2:14:55
    18  * 
    19  */
    20 /*@Order(2)
    21 @Component
    22 @Aspect*/
    23 public class ValidateArgs {
    24     
    25     //@Before("execution(* com.jason.spring.aop.impl.ArithmeticCaculator.*(..))")
    26     public void validateArgs(JoinPoint joinPoint){
    27         System.out.println("validate:" + Arrays.asList(joinPoint.getArgs()));
    28     }
    29 
    30 }
    Main.java
     1 package com.jason.spring.aop.impl;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class Main {
     7     
     8     public static void main(String[] args) {
     9         
    10         //1.创建Spring 的IOC 容器
    11         ApplicationContext ctx = new ClassPathXmlApplicationContext("aop-xml.xml");
    12         
    13         //2.从IOC 容器中获取 bean实例
    14         ArithmeticCaculator arithmeticCaculator = (ArithmeticCaculator) ctx.getBean(ArithmeticCaculator.class);
    15         
    16         //3.使用bean
    17         int result = arithmeticCaculator.add(1, 2);
    18         System.out.println(result);
    19         
    20         result = arithmeticCaculator.div(1, 2);
    21         System.out.println(result);
    22         
    23         
    24     }
    25 
    26 }

  • 相关阅读:
    存储过程的设计规则
    企业管理器里删除不需要的注册
    SQL Server 大数据量插入和索引关系
    【2011520】无法使用主机名连接数据库
    SQL Server 查看存储过程
    SQL Server dbcc inputbuffer
    如何选择行版本的隔离级别
    ObjectiveC中Selector基本概念和操作
    Objectivec的@property 详解
    objectivec 关键字和概念
  • 原文地址:https://www.cnblogs.com/jasonHome/p/6137702.html
Copyright © 2011-2022 走看看