@EnableAspectJAutoProxy 停用我的 bean 定义
@EnableAspectJAutoProxy deactivate my bean definition
我在 IDEA 中设置了一个新的 Spring App(不是 spring boot),并手动下载了 aspectjweaver,
写下面的代码练习aop。
根配置class是:
@Configuration
/*@EnableAspectJAutoProxy*/
@ComponentScan
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext();
ctx.register(Main.class);
ctx.refresh();
Performance performance=ctx.getBean(WoodStock.class);
//System.out.println(ctx.getBean(Audience.class));
performance.performance();
}
}
项目布局为:
+com.dawn.www
-Main.java
+aspect
-Audience.java
+music
-Performance.java
-WoodStock.java
我希望 Audience
成为 WoodStock
的一个方面(在 spring 中看到它的实际效果)
@Aspect
@Component
public class Audience {
@Before("execution(* com.dawn.www.music.Performance.performance(..))")
public void silenceCellPhones(){
System.out.println("-----------Silencing cell phones");
}
}
Performance
是一个简单的接口,由 WoodStock
实现
public interface Performance {
void performance();
}
@Component
public class WoodStock implements Performance{
@Override
public void performance() {
System.out.println("WoodStock Performance start,singer singing+++++");
}
}
@ComponentScan
应该找到在应用程序上下文中定义的 WoodStock
bean,但是当我 运行 它时:
No qualifying bean of type 'com.dawn.www.music.WoodStock' available
但是当我注释掉 @EnableAspectJAutoProxy
时,WoodStock 可以从
应用上下文?这就是为什么?
Performance performance=ctx.getBean(Performance.class);
Spring Aop在不使用CGLIB时只支持接口级代理,所以不要使用class,使用接口
- 当您使用@EnableAspecjAutoProxy 时,spring 将自动
为所有匹配的 bean 创建代理(即通过 Audience 方面的 WoodStock)。
- 现在,由于您还没有使用 'proxyTargetClass=true'
@EnableAspectJAutoProxy,它将返回到 JDK 代理而不是
CGLIB.
- JDK代理是基于接口的,因此你的代理是类型
'Performance'.
- 这就是您收到“没有符合条件的类型的 bean”的原因
'com.dawn.www.music.WoodStock' available' 当您尝试查找 bean 时
使用 WoodStock 类型
- 现在,在注释掉@EnableAspectJAutoProxy 之后,WoodStock 变成了
简单的 bean,可以通过 ctx.getBean(..)
访问
- 与 'proxyTargetClass=true',CGLIB 代理已启用并创建
WoodStock 类型的代理
建议
Use 'proxyTargetClass=true' with ctx.getBean(WoodStock.class)
或
Use 'proxyTargetClass=false' with ctx.getBean(Performance.class)
我在 IDEA 中设置了一个新的 Spring App(不是 spring boot),并手动下载了 aspectjweaver, 写下面的代码练习aop。
根配置class是:
@Configuration
/*@EnableAspectJAutoProxy*/
@ComponentScan
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext();
ctx.register(Main.class);
ctx.refresh();
Performance performance=ctx.getBean(WoodStock.class);
//System.out.println(ctx.getBean(Audience.class));
performance.performance();
}
}
项目布局为:
+com.dawn.www
-Main.java
+aspect
-Audience.java
+music
-Performance.java
-WoodStock.java
我希望 Audience
成为 WoodStock
的一个方面(在 spring 中看到它的实际效果)
@Aspect
@Component
public class Audience {
@Before("execution(* com.dawn.www.music.Performance.performance(..))")
public void silenceCellPhones(){
System.out.println("-----------Silencing cell phones");
}
}
Performance
是一个简单的接口,由 WoodStock
public interface Performance {
void performance();
}
@Component
public class WoodStock implements Performance{
@Override
public void performance() {
System.out.println("WoodStock Performance start,singer singing+++++");
}
}
@ComponentScan
应该找到在应用程序上下文中定义的 WoodStock
bean,但是当我 运行 它时:
No qualifying bean of type 'com.dawn.www.music.WoodStock' available
但是当我注释掉 @EnableAspectJAutoProxy
时,WoodStock 可以从
应用上下文?这就是为什么?
Performance performance=ctx.getBean(Performance.class);
Spring Aop在不使用CGLIB时只支持接口级代理,所以不要使用class,使用接口
- 当您使用@EnableAspecjAutoProxy 时,spring 将自动 为所有匹配的 bean 创建代理(即通过 Audience 方面的 WoodStock)。
- 现在,由于您还没有使用 'proxyTargetClass=true' @EnableAspectJAutoProxy,它将返回到 JDK 代理而不是 CGLIB.
- JDK代理是基于接口的,因此你的代理是类型 'Performance'.
- 这就是您收到“没有符合条件的类型的 bean”的原因 'com.dawn.www.music.WoodStock' available' 当您尝试查找 bean 时 使用 WoodStock 类型
- 现在,在注释掉@EnableAspectJAutoProxy 之后,WoodStock 变成了 简单的 bean,可以通过 ctx.getBean(..) 访问
- 与 'proxyTargetClass=true',CGLIB 代理已启用并创建 WoodStock 类型的代理
建议
Use 'proxyTargetClass=true' with ctx.getBean(WoodStock.class)
或
Use 'proxyTargetClass=false' with ctx.getBean(Performance.class)