@EnableAspectJAutoProxy取消激活我的bean定义

问题描述 投票:0回答:2

我在IDEA中设置了一个新的Spring App(而不是spring boot),并手动下载了aspectjweaver,编写了以下代码来练习aop。

根配置类是:

@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

我希望AudienceWoodStock的一个方面(在春天看到它在行动)

@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应该找到在应用程序上下文中定义的WoodStockbean,但是当我运行它时:

   No qualifying bean of type 'com.dawn.www.music.WoodStock' available  

但是当我评论出@EnableAspectJAutoProxy时,WoodStock可以从应用程序环境中获取?这就是为什么?

spring aop spring-aop
2个回答
0
投票
  1. 当您使用@EnableAspecjAutoProxy时,spring将自动为所有匹配的bean创建代理(即WoodStock via Audience方面)。
  2. 现在,由于你没有在@EnableAspectJAutoProxy上使用'proxyTargetClass = true',它将回退到JDK代理而不是CGLIB。
  3. JDK代理是基于接口的,因此您的代理是“性能”类型。
  4. 这就是为什么当你尝试使用WoodStock类型找到豆子时,你会得到'没有类型的合格豆'com.dawn.www.music.WoodStock'可用'
  5. 现在,在注释掉@EnableAspectJAutoProxy后,WoodStock成为一个简单的bean,可以通过ctx.getBean(..)访问
  6. 使用'proxyTargetClass = true',启用CGLIB代理并创建WoodStock类型的代理

建议

使用'proxyTargetClass = true'和ctx.getBean(WoodStock.class)

要么

将'proxyTargetClass = false'与ctx.getBean(Performance.class)一起使用


0
投票

Performance performance=ctx.getBean(Performance.class); Spring Aop仅在不使用CGLIB时支持接口级代理,因此不要使用类,使用接口。

© www.soinside.com 2019 - 2024. All rights reserved.