I'm learning how to use AspectJ expressions using the book "Spring starts here" and after running the same program 5 times(It was ok) a change in the AspectJ expression made an exception that said
Exception in thread "main"
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type
'julian.gonzalezlopez.aop.Comment.CommentRepository'
available
That error only happends if the AspectJ expression fits the criterea
Aspecto.java
import java.util.logging.Logger;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@Aspect
@Component
public class Aspecto {
private static final Logger logger = Logger.getLogger(Aspect.class.getName());
@Around("execution (* julian.*.*.Comment.*.*(..))")
public void log(ProceedingJoinPoint joinPoint) {
logger.info("Comenzó un metodo atrapado por el aspecto");
try {
joinPoint.proceed();
}
catch (Throwable e) {
System.err.println(e);
}
logger.info("Terminó");
}
}
CommentRepository.java
import julian.gonzalezlopez.aop.POJO.Comment;
import org.springframework.stereotype.Service;
@Service
public class CommentRepository implements CommentRepositoryInterface {
public void pie(Comment comment){
System.out.println(comment.getText());
System.out.println("Escrito por: " + comment.getOwner());
}
}
Main.java
import julian.gonzalezlopez.aop.Comment.CommentRepository;
import julian.gonzalezlopez.aop.Comment.CommentRepositoryInterface;
import julian.gonzalezlopez.aop.POJO.Comment;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext(ProjectConfig.class);
System.out.println(c);
CommentRepositoryInterface commentRepository = c.getBean(CommentRepository.class);
Comment comment = new Comment("hola","julian");
commentRepository.pie(comment);
}
}
Before we proceed to your main problem, a few hints:
You ought to adhere to naming conventions, e.g. not use upper-case package names, because they are easily confused with class names.
Your logger uses class Aspect
, but probably you want to use Aspecto
. Besides, that is also a bad class name. You should use an aspect name describing what kind of aspect it is, such as LoggingAspect
.
In your screenshot, I can see a class named CommentService
, but in your sample code you use class CommentRepository
with a @Service
annotation. That is utterly confusing. Do you even remember yourself why you did that?
Now, how can you fix your problem? Probably, your config class looks somewhat like this:
@Configuration
@EnableAspectJAutoProxy
public class ProjectConfig {}
I.e., it is missing a @ComponentScan
annotation.
Another possibility is that you actually did add that annotation, but still get the same exception. In that case, you can either fix your main class, searching for a bean of the interface class, ...
CommentRepositoryInterface commentRepository = c.getBean(CommentRepositoryInterface.class);
..., which is what I recommend. As an alternative, you can keep your bean instantiation as-is but modify the way Spring creates proxies:
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan
public class ProjectConfig {}
I warmly recommend to use the first option, because it is cleaner from a design point of view. You have the interface and its implementation already, which is a clean design. Utilise it, do not work around it.