【发布时间】:2019-03-30 05:57:49
【问题描述】:
当使用带有类级别注释的 spring AOP 时,spring context.getBean 似乎总是为每个类创建并返回一个代理或拦截器,无论它们是否具有注释。
此行为仅适用于类级别注释。对于方法级别的注解,或者执行切入点,如果不需要拦截,getBean返回一个POJO。
这是一个错误吗?按照设计?还是我做错了什么?
@Component
@Aspect
public class AspectA {
@Around("@target(myAnnotation)")
public Object process(ProceedingJoinPoint jointPoint, MyAnnotation myAnnotation) throws Throwable {
System.out.println(
"AspectA: myAnnotation target:" + jointPoint.getTarget().getClass().getSimpleName());
System.out.println(" condition:" + myAnnotation.condition());
System.out.println(" key:" + myAnnotation.key());
System.out.println(" value:" + myAnnotation.value());
return jointPoint.proceed();
}
}
@Component("myBean2")
//@MyAnnotation(value="valtest-classLevel2", key="keytest-classLevel2", condition="contest-classLevel2")
public class MyBean2 {
public Integer testAspectCallInt(int i){
System.out.println("MyBean2.testAspectCallInt(i=" + i + ")");
return i+1000;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
String value() default "";
String key() default "";
String condition() default "";
}
@ComponentScan()
@EnableAspectJAutoProxy
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Test.class);
MyBean2 bean = (MyBean2)ctx.getBean("myBean2");
System.out.println(bean.getClass()); // prints CGLIB proxy, even when annotation is commented out on class
bean.testAspectCallInt(12); // calling method
}
}
【问题讨论】:
-
我确定这是设计使然。您是否希望访问代理背后的“真实”bean?如果是这样,请致电
AopUtils.getTargetClass(proxyBean); -
@AndyBrown 不,它会导致一些错误,例如 CGLIB 在尝试创建不相关的单例类的代理时失败,该类没有注解,但有一个私有构造函数。
标签: java spring aop spring-aop