John Lolek John Lolek - 3 months ago 21
Java Question

Spring AOP can't apply advice to interface

I am learning spring the from book the "Spring in Action fourth edition" by Craig Walls. I am trying to apply advice to the method declared by the interface and I am getting Exception. When I apply the same advice to the class which doesn't implement anything, everything works fine.

Spring version - 4.3.2

Help would be appreciated.

Exception:

Exception in thread "main"org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.fifczan.bean.UserService] is defined


Code:

Interface:

package com.fifczan.bean;

public interface Service {

void doTask();
}


Implementation:

package com.fifczan.bean;

import org.springframework.stereotype.Component;


@Component
public class UserService implements Service {


public void doTask() {

System.out.println("doing task");

}
}


Aspect:

package com.fifczan;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class UserAspect {

//If i change Service(interface) to UserService(implementation)
//in pointcut I am getting the same exception
@Before("execution(* com.fifczan.bean.Service.doTask(..))")
public void userAdvice(){
System.out.println("doing sth before method doTask");
}
}


Configuration:

package com.fifczan;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AspectJAutoProxyConfig {

}


main :

package com.fifczan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.fifczan.bean.UserService;

public class AspectJAutoProxyTest {
public static void main(String[] args) {

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AspectJAutoProxyConfig.class);

UserService userService= ctx.getBean(UserService.class);
userService.doTask();
}
}

Answer

You're asking for a bean of UserService, which is the concrete class, not the interface. Retrieve or inject a bean of type Service.