嗨,我有一個關于 Spring Aspects 的相當具體的問題,這讓我感到困惑。我玩過 Springs 和 Apsects 并嘗試了一個非常簡單的示例來看看它是如何作業的:
@Component
public class Comment {
private String text;
private String author;
public String get() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
@Aspect
public class LoggingAspect {
@Around("execution(* aop.beans.*.*(..))")
public void log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Start Aspect for method: " joinPoint.getSignature());
joinPoint.proceed();
}
}
我的組態檔:
@Configuration
@ComponentScan("aop.beans")
@EnableAspectJAutoProxy
public class ProjectConfig {
@Bean
public LoggingAspect aspect() {
return new LoggingAspect();
}
}
有了這個,我使用了一個簡單的 Main 方法來玩弄這個概念:
public class Main {
public static void main(String[] args) {
@SuppressWarnings("resource")
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProjectConfig.class);
context.registerShutdownHook();
CommentService service = context.getBean(CommentService.class);
Comment comment = context.getBean(Comment.class);
comment.setAuthor("Andreas");
comment.setText("Hallo.");
service.publishComment(comment);
System.out.println(service.getClass());
}
}
這作業得很好,但是當我改變評論類的層次結構時會發生一些奇怪的事情。我想看看如果該類實作了一個通用介面會發生什么,所以我將其更改如下
public class Comment implements Supplier<String>
我立即收到以下堆疊跟蹤錯誤:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'aop.beans.Comment' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
at aop.Main.main(Main.java:17)
這讓我想知道為什么會這樣?如果我洗掉通用超級介面或方面 bean,一切都可以正常作業,但兩者似乎都不太好。有人可以提供解釋嗎?如果類具有通用超類,Spring 是否無法創建代理物件?
編輯:解決方案在評論中:) 我在Spring Proxy Mechanism Documentation中找到了有關該機制的更多檔案
uj5u.com熱心網友回復:
這是因為 Spring 實作 AOP 的方式。
當代理類(Comment在您的情況下)未實作任何介面時,將使用 CGLib 代理。基本上,它生成一個類,它是代理類的子類。因此,您可以getBean按父母的班級。
當有實作的介面時,Spring 使用 JDK 動態代理,它不擴展代理類,而是實作其所有介面,因此您無法通過它的類找到 bean。
這就是為什么按介面而不是按類自動裝配 bean 始終是一個好習慣。
解決方案
- 您可以通過注釋配置類來強制 Spring 為 AspectJ 使用 CGLib 代理
@EnableAspectJAutoProxy(proxyTargetClass = true)。 - 如果要使用 JDK 動態代理,請創建介面
Comment,然后使用context.getBean(YourInterfaceName.class).
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/459170.html
下一篇:在SQL中組合兩個查詢
