@EnableAspectJAutoProxy停用我的bean定义

时间:2019-03-01 10:50:12

标签: spring aop spring-aop

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

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

但是当我注释掉@EnableAspectJAutoProxy时,可以从 应用程序上下文?这是为什么?

2 个答案:

答案 0 :(得分:0)

@Test public void scrape() throws Exception { boolean exceptionHappend = false; try { SessionTimoutClassWithGettersSettersresult = testScraper("/scrape/timeoutsession.html", "https://cantShow.html"); } catch (SessionTimeoutException e) { exceptionHappend = true; } assertTrue(exceptionHappend); details(result, "imgs/error.png","Your session has timed out. You will need to log back in to continue shopping."); } 不使用CGLIB时,Spring Aop仅支持接口级代理,因此不要使用类,请使用接口。

答案 1 :(得分:0)

  1. 使用@EnableAspecjAutoProxy时,spring会自动 为所有匹配的bean(即通过“受众群体”方面的WoodStock)创建代理。
  2. 现在,由于您尚未在以下位置使用'proxyTargetClass = true' @EnableAspectJAutoProxy,它将回退到JDK代理而不是 CGLIB。
  3. JDK代理基于接口,因此您的代理类型 “性能”。
  4. 这就是为什么您获得“没有合格的Bean类型的原因 当您尝试查找bean时,“ com.dawn.www.music.WoodStock”可用 使用WoodStock类型
  5. 现在,在注释掉@EnableAspectJAutoProxy之后,WoodStock成为 简单的bean,可通过ctx.getBean(..)
  6. 访问
  7. 使用'proxyTargetClass = true',启用CGLIB代理并创建 WoodStock类型的代理

建议

  

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

  

在ctx.getBean(Performance.class)中使用'proxyTargetClass = false'