Search code examples
springaopspring-aop

@EnableAspectJAutoProxy deactivate my bean definition


I setting up a new Spring App(not spring boot) in IDEA,and manual download aspectjweaver, writing the following code to practice aop.

A root configuration class is:

@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();
     }
}

and the project layout is:

+com.dawn.www
  -Main.java
  +aspect
    -Audience.java
  +music
    -Performance.java
    -WoodStock.java

I want the Audience being the aspect of WoodStock(seeing it in spring in action)

@Aspect
@Component
public class Audience {
    @Before("execution(* com.dawn.www.music.Performance.performance(..))")
    public void silenceCellPhones(){
        System.out.println("-----------Silencing cell phones");
    }
}

Performance is a simple interface which implements by 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 should find theWoodStockbean which is defined in application context,however when I run it:

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

but when I comment out @EnableAspectJAutoProxy, WoodStock can be fetched from application context?that's why?


Solution

    1. When you are using @EnableAspecjAutoProxy, spring will automatically create proxy for all the matching beans(i.e. WoodStock via Audience aspect).
    2. Now, Since you haven't used 'proxyTargetClass=true' on @EnableAspectJAutoProxy, it will fall back on JDK proxy instead of CGLIB.
    3. JDK proxy is interface based, hence your proxy is of type 'Performance'.
    4. Thats the reason you are getting 'No qualifying bean of type 'com.dawn.www.music.WoodStock' available' when you try to find bean using WoodStock type
    5. Now, after commenting out @EnableAspectJAutoProxy, WoodStock becomes a simple bean and is accessible via ctx.getBean(..)
    6. with 'proxyTargetClass=true', CGLIB proxy is enabled and it creates proxy of type WoodStock

    Suggestions

    Use 'proxyTargetClass=true' with ctx.getBean(WoodStock.class)

    or

    Use 'proxyTargetClass=false' with ctx.getBean(Performance.class)