0

I'm trying to use the code in this question, as base for my own AOP logging. However, when I add the advices, the application context no longer loads.

@Aspect
@Component
public class MyLogger {

    /** Handle to the log file */
    private final Log log = LogFactory.getLog(getClass());

    public MyLogger () {}

    @AfterReturning("execution(* org.my.package.*.*(..))")
    public void logMethodAccessAfter(JoinPoint joinPoint) {
        log.info("***** Completed: " + joinPoint.getSignature().getName() + " *****");
        System.out.println("***** Completed: " + joinPoint.getSignature().getName() + " *****");
    }

    @Before("execution(* org.my.package.*.*(..))")
    public void logMethodAccessBefore(JoinPoint joinPoint) {
        log.info("***** Starting: " + joinPoint.getSignature().getName() + " *****");
        System.out.println("***** Starting: " + joinPoint.getSignature().getName() + " *****");
    }
}

Exception stack, a whole bunch of Could not autowire field:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxxxxx.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119)

UserService is a completely unrelated class, and everything runs again if I comment out the methods annotated with @AfterReturning and @Before.

AOP dependencies are there:

[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.3.0.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:1.3.0.RELEASE:compile

Any idea why this happens? I don't even know where to start looking.

Community
  • 1
  • 1
garci560
  • 2,993
  • 4
  • 25
  • 34
  • Does the `UserService` implement an interface? – fateddy Mar 17 '16 at 16:34
  • @fateddy No, it doesn't... So I need to create interfaces for all beans in the package matched by the advices, in this case `org.my.package`, right? – garci560 Mar 17 '16 at 17:01
  • 1
    No - you do not need to create interfaces for your beans. The problem could relate to how spring creates AOP proxies: JDK-Dynamic Proxies (default) vs. CGLIB Proxies. Enable CGLIB Proxying by adding `@EnableAspectJAutoProxy(proxyTargetClass=true)` to one of your config-classes. See also this answer here: http://stackoverflow.com/a/35579802/4516887. – fateddy Mar 17 '16 at 19:15

1 Answers1

2

Your bean UserService is now a proxy and doesn't match the required type for injection. Possible workaround:

  • Create an interface UserService and a service class that implement the interface
  • Enable CGLIB based proxy (@EnableAspectJAutoProxy(proxyTargetClass=true))
  • Weave aspect at compile time.
JEY
  • 6,973
  • 1
  • 36
  • 51