Separate the pointcut and aspect(advice), and allow user to override them
See original GitHub issueHello,
We have faced a problem with proxying a @Component
that has final methods.
Since CGLIB cannot proxy the final methods (final classes was handled by #188), it produces a log like this:
org.springframework.aop.framework.CglibAopProxy@263 - Unable to proxy interface-implementing method [public final void com.example.Foo.execute(com.example.Bar)] because it is marked as final: Consider using interface-based JDK proxies instead!
Then, the component was not properly dependency injected and failed with NPE at runtime.
The underlying problem is that the SpringComponentAspect
and its friends are too generalized to grab many of the application’s beans. Yet, there is no control available to users.
We want to have a control for excluding certain classes or packages for proxying. Or, maybe proxy only the specific set of beans.
One way is to override the aspect bean(e.g. SpringComponentAspect
). However, since it is an aspect that contains both the pointcuts and the proxy logic(advice), the overriding custom bean needs to copy/paste the advice from the original bean if I were to change only the pointcut. This is not an ideal approach.
I would like to suggest, rather than using Aspect, use the underlying spring infrastructure for the AOP.
Since chaos-monkey-spring-boot
is a library, it is preferable to provide a flexible approach rather than an aspect for creating proxies.
The DefaultAdvisorAutoProxyCreator
allows dynamically creating proxies by taking advisors.
So, for example with sudo code:
// just a marker interface for the advisor to the component classes
public interface ComponentAdvisor implements Advisor {
}
// just a marker interface for the advice to the component classes
public interface ComponentAdvice implements Advice {
}
@ConditionalOnMissingBean
@Bean
public ComponentAdvice componentAdvice() {
// the advice logic for @Component beans. e.g. introduction/interceptor
}
@ConditionalOnMissingBean
@Bean
public ComponentAdvisor componentAdvisor(ObjectProvider<ComponentAdvice> advices) {
// provide default pointcut for @Component beans
}
@ConditionalOnMissingBean
@Bean
public DefaultAdvisorAutoProxyCreator componentProxyCreator(ObjectProvider<ComponentAdvisor> advisors) {
// create proxy creator based on the advisors for @Component beans
}
This way, since these beans are @ConditionalOnMissingBean
, the user can provide own implementation to override the default ones independently.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
@ttddyy bean watchers and
watchCustomServices
are two separate things. Usechaos.monkey.watcher.beans
instead.I am facing the same issue - “Could not generate CGLIB subclass of class xxxxx” and application doesn’t boot-up. Happens for a class with private or final methods. Can’t change the code as these classes are part of third-party libraries.
Is this being fixed in the upcoming version of the framework? Any workaround?