基于XML配置的AOP实现日志打印

Posted bwlu---ed

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于XML配置的AOP实现日志打印相关的知识,希望对你有一定的参考价值。

Spring中可以使用注解或XML文件配置的方式实现AOP。
1、导入jar包

  • com.springsource.net.sf.cglib -2.2.0.jar
  • com.springsource.org.aopalliance-1.0.0 .jar
  • com.springsource.org.aspectj.weaver-1.6.8 .RELEASE.jar
  • commons-logging-1.1.3. jar
  • spring-aop-4.0.0.RELEASE.jar
  • spring-aspects-4.0.0.RELEASE.jar
  • spring-beans-4.0.0.RELEASE.jar
  • spring-context-4.0.0.RELEASE.jar
  • spring-core-4.0.0.RELEASE.jar
  • spring-expression-4.0.0.RELEASE.jar

aspectaop相关jar包 密码:25nc

Spring相关jar包 密码:xp57

2、新建代理类和切面类

技术分享
 1 @Component
 2 public class MathCalculator {
 3     public void add(int i, int j) {
 4         int result=i+j;
 5         System.out.println("目标方法add(int)执行了");
 6     }
 7     public void sub(int i, int j) {
 8         int result=i-j;
 9         System.out.println("目标方法sub执行了");
10     }
11     public void mult(int i, int j) {
12         int result=i*j;
13         System.out.println("目标方法mult执行了");
14     }
15     public void div(int i, int j) {
16         int result=i/j;
17         System.out.println("目标方法div执行了");
18     }
19 }
MathCalculator

切面类1:LogAspectp1:声明4中通知方法,Before、After、AfterThrowing、AfterReturning

 1 public class LogAspectp1{
 2     public void showBeginLog(JoinPoint jPoint){
 3         Object[] args = jPoint.getArgs();//获取方法参数
 4         List<Object> asList = Arrays.asList(args);//转化成List集合
 5         Signature signature = jPoint.getSignature();
 6         String name = signature.getName();//获取方法的名字
 7         System.out.println("LogAspectp1-----AOP日志开始");
 8         System.out.println("目标方法名:"+name+",参数列表:"+asList);
 9     }
10     public void showAfterLog(){
11         System.out.println("LogAspectp1-----AOP方法结束");
12     }
13     public void showExceptionLog(Exception ex){
14         System.out.println("LogAspectp1-----AOP方法异常");
15         System.out.println("异常信息:"+ex.getMessage());
16     }
17     public void showReturnLog(Object result){
18         System.out.println("方法返回值:"+result);
19         System.out.println("LogAspectp1-----AOP方法最终返回");
20     }
21 }

切面类2:LogAspectp2:声明Around通知方法,代替前面的4中通知

 1 public class LogAspectp2{
 2     public Object showLog(ProceedingJoinPoint point){
 3         Object[] args = point.getArgs();
 4         List<Object> asList = Arrays.asList(args);
 5         Signature signature = point.getSignature();
 6         String name = signature.getName();
 7         Object result = null;
 8         try {
 9             try {
10                 //目标方法之前要执行的操作,相当于@before
11                 System.out.println("LogAspect2-----[环绕日志]"+name+"开始了,参数为:"+asList);
12                 //调用目标方法
13                 result = point.proceed(args);
14             } finally {
15                 //方法最终结束时执行的操作,相当于@after
16                 System.out.println("LogAspect2-----[环绕日志]"+name+"结束了!");
17             }
18             //目标方法正常执行之后的操作,相当于@AfterReturning
19             System.out.println("LogAspect2-----[环绕日志]"+name+"返回了,返回值为:"+result);
20         } catch (Throwable e) {
21             //目标方法抛出异常信息之后的操作,相当于@AfterThrowing
22             System.out.println("LogAspect2-----[环绕日志]"+name+"出异常了,异常对象为:"+e);
23             throw new RuntimeException(e.getMessage());
24         }
25         return result;
26     }
27 }

3、在Spring的配置文件applicationContext.xml中进行配置

 1 <!-- 将需要加载到IOC容器中的bean配置好 -->
 2 <bean id="mathCalculator" class="com.bwlu.common.MathCalculator"></bean>
 3 <bean id="logAspectp1" class="com.bwlu.common.LogAspectp1"></bean>
 4 <bean id="logAspectp2" class="com.bwlu.common.LogAspectp2"></bean>
 5 <!-- 配置AOP,需要导入AOP名称空间 -->
 6 <aop:config>
 7     <!-- 声明切入点表达式 -->
 8     <aop:pointcut expression="execution(public * com.bwlu.aop.MathCalculatorImpl.*(..))" id="pointcut"/>
 9     <!-- 配置日志切面类,引用前面的类 ,通过order属性控制优先级-->
10     <aop:aspect ref="logAspectp1" order="20">
11         <!-- 通过method属性指定切面类的切面方法,通过pointcut-ref指定切入点表达式 -->
12         <aop:before method="showBeginLog" pointcut-ref="pointcut"/>
13         <aop:after method="showAfterLog" pointcut-ref="pointcut"/>
14         <aop:after-throwing method="showExceptionLog" pointcut-ref="pointcut" throwing="ex"/>
15         <aop:after-returning method="showReturnLog" pointcut-ref="pointcut" returning="result"/>
16     </aop:aspect>
17     <aop:aspect ref="logAspectp2" order="10">
18         <aop:around method="showLog" pointcut-ref="pointcut"/>
19     </aop:aspect>
20 </aop:config>

4、新建Junit测试类进行测试

 1 ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
 2 @Test
 3 public void test() {
 4     //需要进行强转,如果该类实现了一个接口,那么获取到的将不是该类的对象,需要强转
 5     //MathCalculatorImpl实现了MathCalculator接口,则
 6     //MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculatorImpl");
 7     MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculator");
 8     bean.add(10, 5);
 9     System.out.println();
10     bean.add(10.0, 5);
11     System.out.println();
12     bean.sub(10, 5);
13     System.out.println();
14     bean.mult(10, 5);
15     System.out.println();
16     bean.div(10, 0);
17 }

运行结果:

技术分享
 1 LogAspectp2-----[环绕日志]add开始了,参数为:[10, 5]
 2 LogAspectp1-----AOP日志开始
 3 目标方法名:add,参数列表:[10, 5]
 4 目标方法add(int)执行了
 5 LogAspectp1-----AOP方法结束
 6 方法返回值:null
 7 LogAspectp1-----AOP方法最终返回
 8 LogAspectp2-----[环绕日志]add结束了!
 9 LogAspectp2-----[环绕日志]add返回了,返回值为:null
10 
11 LogAspectp2-----[环绕日志]add开始了,参数为:[10.0, 5.0]
12 LogAspectp1-----AOP日志开始
13 目标方法名:add,参数列表:[10.0, 5.0]
14 目标方法add(double)执行了
15 LogAspectp1-----AOP方法结束
16 方法返回值:15.0
17 LogAspectp1-----AOP方法最终返回
18 LogAspectp2-----[环绕日志]add结束了!
19 LogAspectp2-----[环绕日志]add返回了,返回值为:15.0
20 
21 LogAspectp2-----[环绕日志]sub开始了,参数为:[10, 5]
22 LogAspectp1-----AOP日志开始
23 目标方法名:sub,参数列表:[10, 5]
24 目标方法sub执行了
25 LogAspectp1-----AOP方法结束
26 方法返回值:null
27 LogAspectp1-----AOP方法最终返回
28 LogAspectp2-----[环绕日志]sub结束了!
29 LogAspectp2-----[环绕日志]sub返回了,返回值为:null
30 
31 LogAspectp2-----[环绕日志]mult开始了,参数为:[10, 5]
32 LogAspectp1-----AOP日志开始
33 目标方法名:mult,参数列表:[10, 5]
34 目标方法mult执行了
35 LogAspectp1-----AOP方法结束
36 方法返回值:null
37 LogAspectp1-----AOP方法最终返回
38 LogAspectp2-----[环绕日志]mult结束了!
39 LogAspectp2-----[环绕日志]mult返回了,返回值为:null
40 
41 LogAspectp2-----[环绕日志]div开始了,参数为:[10, 0]
42 LogAspectp1-----AOP日志开始
43 目标方法名:div,参数列表:[10, 0]
44 LogAspectp1-----AOP方法结束
45 LogAspectp1-----AOP方法异常
46 异常信息:/ by zero
47 LogAspectp2-----[环绕日志]div结束了!
48 LogAspectp2-----[环绕日志]div出异常了,异常对象为:java.lang.ArithmeticException: / by zero
运行结果

 


以上是关于基于XML配置的AOP实现日志打印的主要内容,如果未能解决你的问题,请参考以下文章

Spring Aop实现方式(注解和Xml)

Spring Aop实现方式(注解和Xml)

JAVA之AOP

springboot aop + logback + 统一异常处理 打印日志

SpringBoot 配置 AOP 打印日志

Spring AOP配置-xml