I need some help with creating Aspect bean.
I have module A
, B
... and module starter-x
. I have a couple of Aspects declared in module starter-x, and configurations for them(like spring data repository monitoring aspect with configuration annotated with @ConditionalOnClass(Repository.class)
etc).
Here's how example configuration looks like
@Configuration
@ConditionalOnClass(Repository.class)
public class RepositoryMonitoringConfiguration {
@Bean
@Qualifier("RepositoryCallCounter")
public DatabaseCallCounter repositoryCounter(){
return new RepositoryCallCounter();
}
}
And i have class with @Aspect
annotation(but not @Component
, when i create bean with @Component
not @Configuration
, everything is ok)
So my question, is it possible to provide aspect bean in @Configuration
class, without @Component
annotation on it (I want to create cool starter with auto configuration)
It's possible, you just need to mark the configuration class like this:
@Configuration
@EnableAspectJAutoProxy
@ConditionalOnClass(Repository.class)
public class RepositoryMonitoringConfiguration {
@Bean
public DatabaseCallCounter repositoryCounter(){
return new RepositoryCallCounter();
}
}
I encountered same problem as you. And I figured out the cause.
The solution is to exclude your Config class from @Around
like following code.
package hello.hellospring.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Slf4j @Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..)) && !target(your config class)")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
log.info("START: " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long finish = System.currentTimeMillis();
log.info("END: " + joinPoint + " " + (finish - start) + "ms");
}
}
}
You probably configured @Around
to root package and its subpackages.
And that means @Around
method is also applied to the configuration class.
So, when the spring tries to make a bean for not only AOP but also other else,
Spring finds AOP class in container that you want to make.
But, of course, there doesn't exist AOP class
if @Component
is not applied to AOP class.
And Spring thinks AOP references AOP.
So Spring makes an error like following log.
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
memberController defined in file [/Users/macbook/Desktop/git/hello-spring/build/classes/java/main/hello/hellospring/controller/MemberController.class]
↓
memberService defined in class path resource [hello/hellospring/SpringConfig.class]
┌─────┐
| timeTraceAop defined in class path resource [hello/hellospring/SpringConfig.class]
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.