- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
@Transactional
@Component
@EntranceLog
public class TransferServiceImpl implements TransferService {
xxxx
}
我有一个带有 Transactional
注释和 Component
注释的类。 EntranceLog
是我自定义的通过aop打印日志的注解。
public class LogProxyCreator extends AbstractAutoProxyCreator implements ApplicationContextAware {
private static final LogInterceptor LOG = new LogInterceptor();
private static Logger log = LoggerFactory.getLogger(LogProxyCreator.class);
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String s, TargetSource targetSource) throws BeansException {
Annotation anno = null;
for (Annotation annotationTemp : beanClass.getAnnotations()) {
Log temp = annotationTemp.annotationType().getAnnotation(EntranceLog.class);
if (temp != null) {
anno = temp;
break;
}
}
if (anno == null) {
return null;
}
Object[] additional = new Object[]{LOG};
log.error(beanClass.getName() + " has register the fc log.");
return additional;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
LOG.setContext(applicationContext);
}
}
当我的应用程序启动时,bean TransferServiceImpl 启动,但 beanClass.getAnnotations()
无法获取任何注释。为什么?
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Log(logName = "entrance")
public @interface EntranceLog {
@AliasFor(
annotation = Log.class,
attribute = "subLogName"
)
String logName() default "";
@AliasFor(
annotation = Log.class,
attribute = "openInfoLog"
)
boolean openInfoLog() default false;
}
这是我的注释。
最佳答案
Spring @Transactional
已经是 AOP 处理的注释,因此添加您自己的注释将需要一些额外的工作。让我解释一下 Spring AOP 和 @Transactional
是如何实现的有效。
Spring 有两种实现 AOP 的方式,如果类实现了接口(interface),它可以使用标准的 JDK 代理,如果类没有实现接口(interface),它将使用 CGLib 创建一个新的子类在运行时发出字节码。除非您非常小心,否则您几乎总是会使用 Spring AOP 获得 CGLib 代理。
当 Spring 遇到 @Transactional
(类或方法级别)它使用 CGLib 创建一个新的子类,您可以将此类视为装饰器,它将所有调用转发到您的实现类。之前和之后(围绕建议)它检查 @Transactional
注解属性,并检查线程本地存储以查看事务是否已存在,如果没有事务,则创建一个事务,并记住它,以便之后可以提交它。如果您在 Transactional
内设置断点方法并查看调用堆栈,您将看到对实现的调用来自装饰器类,并且没有其源代码。
在您的情况下,添加到应用程序上下文的 bean 不是您的 TransferServiceImpl
bean,而是 Spring 在发现 @Transactional
时创建的 CGLib 代理您的类上的注释,它将被命名为 TransferServiceImpl$$FastClassBySpringCGLIB$$<hexstring>
- 这个类没有@EntranceLog
注释,这就是为什么你自己的方面不起作用。
我自己从未遇到过这个问题,因为我通常会尝试避免 AOP,或者总是在已经由 Spring 代理的 CGLib 类上避免 AOP。除非您想深入研究 Spring 源代码,或者找到 Spring 开发团队中的某人来帮助您完成此操作,否则我建议您创建另一层间接层,这样您就不需要在同一个类中处理两个方面。
关于java - 为什么无法从beanClass获取注解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42411642/
我正在使用 EJB 3.0,当我调用要执行的方法时,出现以下错误: java.lang.RuntimeException: Could not resolve beanClass method fro
我是一名优秀的程序员,十分优秀!