关于AOP切面注解失效的老式解决办法
1.AOP底层是基于反射的
a)先来一个代理接口:
1 ackage com.laola.arthimetic; 2 3 import org.springframework.stereotype.Component; 4 5 public interface Arthimetic { //这个接口就是用来接受代理对象的 6 int add(int i,int j); 7 int sub(int i,int j); 8 int mul(int i,int j); 9 int div(int i,int j); 10 }
b) 实现类:
package com.laola.arthimetic; import org.springframework.stereotype.Component; @Component public class ArthimeticImpl implements Arthimetic{ //实现此接口 @Override public int add(int i, int j) { return i+j; } @Override public int sub(int i, int j) { return i-j; } @Override public int mul(int i, int j) { return i*j; } @Override public int div(int i, int j) { return i/j; } }
2.日志消息类
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; import java.sql.SQLOutput; import java.util.Arrays; import java.util.List; //注意这里的注解我是没有用的 @Aspect @Component public class LogAspect { // 切面的before方法 public void logbefore(JoinPoint joinPoint){ String name=joinPoint.getSignature().getName(); List<Object> args= Arrays.asList(joinPoint.getArgs()); System.out.println(name+" begin"+args); } //切面的after方法 public void logafter(JoinPoint joinPoint){ String name=joinPoint.getSignature().getName(); System.out.println(name+" end"); }
//切面的returing方法 public void logreturing(JoinPoint joinPoint,Object r){ String name=joinPoint.getSignature().getName(); System.out.println(name+" returing "+r); }
//切面的throwing方法 public void aftethrowing(JoinPoint joinPoint,Exception e) { String name=joinPoint.getSignature().getName(); System.out.println(name+" throwing "+e); } }
3.测试类
import com.laola.arthimetic.Arthimetic; import com.laola.arthimetic.ArthimeticImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class test { //虽然注解比较方便,但有时候jdk或者其他插件版本更新会有切面注解失效等问题的存在,为了省去找解决办法的时间,还是使用bean配置文件 public static void main(String[] args) { ApplicationContext ctx= new ClassPathXmlApplicationContext("beans.xml");
//接口代理 Arthimetic arthimetic=(Arthimetic) ctx.getBean("arthimeticImpl"); int r=arthimetic.div(12,0); System.out.println(r); } }
4.beans.xml文件配置
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd " > <!-- 1.注册bean和切面--> <bean id="arthimeticImpl" class="com.laola.arthimetic.ArthimeticImpl"></bean> <bean id="logaspect" class="LogAspect"></bean> <!-- 2.开始配置--> <aop:config> <!-- 创建一个共有切入点,这样就不用频繁的使用 "execution(* com.laola.arthimetic.Arthimetic.*(..))"了 --> <aop:pointcut id="pointcut" expression="execution(* com.laola.arthimetic.Arthimetic.*(..))"/> <!-- 3.创建切面--> <aop:aspect ref="logaspect" order="1"> <!-- 4.切面方式 --> <aop:before method="logbefore" pointcut-ref="pointcut"/> <aop:after method="logafter" pointcut-ref="pointcut" /> <aop:after-returning method="logreturing" pointcut-ref="pointcut" returning="r"/> <aop:after-throwing method="aftethrowing" pointcut-ref="pointcut" throwing="e"/> </aop:aspect> </aop:config> </beans>
这里面有些命名空间没用到,没啥影响。
5.总结
a. 如果使用idea编写Spring,有些包是没有下载的,比如aspectj-weaver这个jar包,有时候采用注解方式会发现提示中没有@Aspect以及它以下的子注解,所以这个包单独下载或者从本地导入。
b. 一般我们使用配置文件这种形式出错率会少,虽然效率相对较慢,但若这种情况发生在idea上,不会是个大问题,因为它有很好的提示功能。
c. 另外要注意切面的每个细节属性,不然容易报错。
d. 为了减少多次service层的公有方法的代码调用量,一般用pointcut来创建切入点,使用expression=execution(* com.laola.arthimetic.Arthimetic.*(..))"来完成公有方法的调用
e. 另外遇到注解括号内有(name和value两个属性的二选一的,最好选择value)
作者:人迹罕至的那条路
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。