刚刚开始触AOP,什么都不懂就要做东西。在网上看例子,发现别人在切面类上用@annotation加自定义注解就可以拦截使用这个注解的方法。后来看到还有个@args,就以为可以自定义一个参数注解,在方法的参数上使用这个注解后切面可以拦截有这个参数的方法。由是写下如下的代码:
CheckPara.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CheckPara {
public int sub() default 0;
}
UserService.java
@Service("userService")
public class UserService {
public void addUser(@CheckPara int age)
{
System.out.println("age: " + age);
}
}
SubParaHandler.java
@Component
@Aspect
public class SubAgeHandler {
@Before("@args(com.zjs.cglib.test.CheckPara)")
public void subIt() throws Throwable {
System.out.println("fuck!");
return;
}
}
主程序
public class App
{
public static void main( String[] args )
{
ApplicationContext ac = new ClassPathXmlApplicationContext("testBeans.xml");
UserService us = (UserService) ac.getBean("userService");
us.addUser(us);
}
}
运行后发现fuck!没有被打印出来。百度很久无解,只好开VPN去Google国外搜搜。发现http://stackoverflow.com/questions/20121126/spring-aop-args-advice-refuses-to-run,这哥们和我遇到的问题一样。
下面有一个回答给了另一个链接http://stackoverflow.com/questions/16810617/aspectj-java-instrumentation-to-intercept-an-annoted-parameter-call-usage,进去之后第一个回答解决了问题。
原来这种写法AspectJ现在还不支持,是一个wish list上的feature,但还没有实现。
现在@args的正确用法是,自定义一个ElementType.TYPE的注解,这个注解用来修饰自定义类型(比如自己写的一个类),一个方法以这个自定义的类的实例为参数且只能有这唯一一参数,那这个方法在调用时会被匹配@args(自定义注解)的切面拦截。
这次的教训是。。真有问题的时候还必须得google。。