AspectJ + @Configurable

Trying to use both AspectJ and @Configurable with a Spring application.

  • If I load Spring with the @Component annotation in the class, the AspectJ wrapper works and wraps all the target methods, and the @Autowired annotation causes dependency nesting. But a class cannot be created at run time with the new keyword and have dependencies entered.
  • If I load the @Configurable class without an AspectJ bean, all the dependencies are entered correctly on new , but none of the methods are proxied through AspectJ.

How can I do both?

Here is 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(); } } 

Format:

 @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 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()); } } 
  • If I get rid of beans in TestCoreConfig and create an instance of SampleSecuredClass in the test with new and change its annotation to @Configurable , then the service will be introduced, but the aspect does not apply.
  • If I started, like here (by entering SampleSecuredClass as a bean), then the aspect works and the service is entered, but then all objects must be created when the environment starts. I would like to use the @Configurable annotation.
  • If I use both @Configurable and Aspect annotations together, I get an illegal type in constant pool error and the context does not start.

Other pieces of information.

  • I tried several different java agents - both Spring toolkit and aspectjwrapper. without changes.

  • If I include the aop.xml file, then this aspect works, but not @Configurable.

+5
source share
1 answer

This seems to be one of those deep docs diving sessions awaiting :)

First of all, I would org.springframework debug org.springframework for org.springframework , because it would definitely give some meaningful insight into what and when Spring does ...

I believe your problem lies somewhere in the fog of Spring's context life cycles, so I carefully checked the docs, especially around

  • Manually indicating that the bean depends on the configuration aspect depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"

  • ... or a note around @Configurable(preConstruction=true)

If you want dependencies to be entered before the constructor bodies execute

  1. ... or @Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true)

Finally, you can enable Spring dependency checking for object references in a newly created and configured object using the dependencyCheck attribute.

Read the documents carefully, see how and how these images are applied, and please tell us the solution that you will find. This must seem very interesting.

+1
source

Source: https://habr.com/ru/post/1232865/


All Articles