Trying to use both AspectJ and @Configurable
with a Spring application.
@Component
annotation on a class, the AspectJ wrapper works and wraps all targeted methods AND the @Autowired
annotation causes dependencies to be injected. But the class cannot be instantiated at runtime with the new
keyword and have dependencies injected.@Configurable
class without the AspectJ bean, all dependencies are injected correctly on new
but none of the methods are proxied through AspectJ.How can I do both?
Here's my code. Configuration:
@Configuration
@ComponentScan(basePackages="com.example")
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving
public class TestCoreConfig {
@Bean
public SecurityAspect generateSecurityAspect(){
return new SecurityAspect();
}
@Bean
public SampleSecuredClass createSampleClass(){
return new SampleSecuredClass();
}
}
Aspect:
@Aspect
public class SecurityAspect {
@Pointcut("execution(public * *(..))")
public void publicMethod() {}
@Around("publicMethod()")
public boolean test (ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Here!");
joinPoint.proceed();
return true;
}
}
SampleClass:
//@Configurable
@Component
public class SampleSecuredClass {
@Autowired
public SecurityService securityService;
public boolean hasSecurityService(){
return securityService != null;
}
public boolean returnFalse(){
return false;
}
}
And the unit test:
@ContextConfiguration(classes={TestCoreConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecurityAspectComponentTest {
@Autowired
private SampleSecuredClass sampleSecuredClass;
@Test
public void testSecurityRoles(){
//SampleSecuredClass sampleSecuredClass = new SampleSecuredClass();
assertTrue("We need to ensure the the @Configurable annotation injected the services correctly", sampleSecuredClass.hasSecurityService());
assertTrue("We need to ensure the the method has been overwritten", sampleSecuredClass.returnFalse());
}
}
TestCoreConfig
and create an instance of SampleSecuredClass
in the test with new
, and change its annotation to @Configurable
then the service is injected, but the aspect is not applied.SampleSecuredClass
as a bean), then the aspect works and the service is injected, but then all objects have to be created on framework start. I would like to use the @Configurable
annotation.@Configurable
annotation and the Aspect together then I get a illegal type in constant pool
error and the context does not start.Other pieces of information.
I have tried a few different java agents--both spring instrumentation and aspectjwrapper. no change.
If I include an aop.xml file, then the aspect works but not the @Configurable.
This seems one of those deep dives sessions into the docs waiting to happen :)
First of all I'd enable debug logging for org.springframework
because this will definitely provide some meaningful insight into what and when Spring does...
That being said I believe that your problem lies somewhere in the mist of spring's context lifecycles so I'd check out the docs carefully especially around
Manually specifying that the bean depends on the configuration aspect depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"
...or the note around @Configurable(preConstruction=true)
If you want the dependencies to be injected before the constructor bodies execute
@Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true)
Finally you can enable Spring dependency checking for the object references in the newly created and configured object by using the dependencyCheck attribute.
Read the docs carefully, see if and how these hits apply and please let us know the solution you find. It should definitely present itself as a very interesting read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With