0 0

spring aop 拦截 annotation的问题30

    最近写了个自定义的annotation。想用spring的aop拦截并解析出annotation的值。
    但是,发现只能解析到接口的annotation,不能解析到实现类的annotation。这是为什么呢?
   
    annotation定义代码如下:
@Target(ElementType.METHOD)   
@Retention(RetentionPolicy.RUNTIME)   
@Documented  
public @interface MyTest {   
    public String value() default "Hello World!";   
}  


   业务实现类代码为:
@Service("bo")
public class BusinessServiceImp implements BusinessService{
    
    //这里的注解不能获取到。	
	@MyTest("test annotation")
	public String update(){
		System.out.println("update data!");
		return "update return value!";
	}
	
	public void delete(){
		System.out.println("delete data!");
	}
}


    如果将注解放在接口中,将能解析出annotation。
    业务接口定义:
public interface BusinessService {
	//这里的annotation可以获取到。实现类中的却不能获取到。这就是问题所在。纠结啊。
    @MyTest("test annotation")
	public String update();
	
	public void delete();
}

   
    AOP的around方法为:
public Object around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("环绕通知前");

		MethodSignature joinPointObject = (MethodSignature) pjp.getSignature();
		Method method = joinPointObject.getMethod();  
		boolean flag = method.isAnnotationPresent(MyTest.class) ;   
		if(flag){   
			MyTest annotation2 = method.getAnnotation(MyTest.class);  
			System.out.println(method.getName() + "方法上的注解:");
			System.out.println(annotation2.annotationType().getCanonicalName() + " : " + annotation2.value()+"\t");   
		}  

		Object obj = pjp.proceed();
		System.out.println("环绕通知后");
		
		return obj;
	}

   
    通过around的ProceedingJoinPoint对象获取到Method对象。可是获取到的Method对象似乎不是实现类的Method对象,因而解析不出annotation。这是为什么呢?


问题补充:
rocketball 写道
不好意思,前面的很乱
Spring的AOP有两张模式,在默认情况下,如果是目标对象实现了接口的类,采用的JDK动态代理,如果没有则创建一个CGLIB代理,你可以用CGLIB代理试试看,在你配置中修改为:
<aop:aspectj-autoproxy proxy-target-class="true"/> 就是在你原来配置的地方加上proxy-target-class="true" 让它用CGLIB代理


你说的这个我知道。只是我不想采用cglib的处理方式能获取到实现类的注解吗?
2011年1月30日 13:40

5个答案 按时间排序 按投票排序

0 0

用spring 的 AnnotationUtils.findAnnotation(Method method, Class<A> annotationType)

2019年11月28日 11:42
0 0


@Target(ElementType.METHOD)   
@Retention(RetentionPolicy.RUNTIME)   
@Inherited
@Documented  
public @interface MyTest {   
    public String value() default "Hello World!";   
}  



加上 @Inherited试下

2013年1月31日 17:21
0 0

简单的说,你不能把annotation放在interface method上面,就能够实现implements class method环绕。

如果你的annotation放在接口方法上面,那么只能够环绕这个接口方法,其他override的方法是不能够被环绕的,因为你的annotation存在的class有个全限定名字,也就是com.yourpackagename.Classname的xxxmethod,aop环绕不可能找到com.yourpackagename.SubClassname的xxxmethod

我自己也没有在aspectj里面找到接口环绕的命名规则

所以综上你想实现功能,在aop里面是没有直接的实现方法的

2011年2月01日 11:51
0 0

不好意思,前面的很乱
Spring的AOP有两张模式,在默认情况下,如果是目标对象实现了接口的类,采用的JDK动态代理,如果没有则创建一个CGLIB代理,你可以用CGLIB代理试试看,在你配置中修改为:
<aop:aspectj-autoproxy proxy-target-class="true"/> 就是在你原来配置的地方加上proxy-target-class="true" 让它用CGLIB代理

2011年1月30日 16:55
0 0

Spring的AOP有两张模式,在默认情况下,如果是目标对象实现了接口的类,采用的JDK动态代理,如果没有则创建一个CGLIB代理,你可以用CGLIB代理试试看,在你配置中修改为:
&#56256;<aop:aspectj-autoproxy /><aop:aspectj-autoproxy /><aop:aspectj-autoproxy /><aop:aspectj-<aop:aspectj-autoproxy proxy-target-class="true"/> 就是在你原来配置的地方加上proxy-target-class="true" 让它用CGLIB代理

2011年1月30日 16:54

相关推荐

Global site tag (gtag.js) - Google Analytics