So what i want is to apply an specific Spring Aspect to my classes when an profile is active, but i can't find a solution, i try the way proposed in http://city81.blogspot.com/2012/05/using-spring-profile-with.html but is quite old and don't work in my case, i have a Spring Started project for testing and i do the following based on the link:
configuring the Application:
@Configuration
@ComponentScan(basePackages= {
"demo",
"demo.aspect"
})
@EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class Application {
@Bean
@Profile("asdasd") //testing profile to bean level
public TestAspect testAspect() { //this allow @autowired in my aspect
TestAspect aspect = Aspects.aspectOf(TestAspect.class);
return aspect;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My Aspect:
//TESTING IN ALL THIS WAYS BUT NOTHING
//@Component
//@Profile("asdasd")
@Configurable
//@Configuration
@Aspect
public class TestAspect{
public static final Logger LOGGER = LogManager.getLogger(testControllerEX.class);
@Autowired
private testService testService;
public TestAspect() {
LOGGER.info("TEST ASPECT INITIALIZED");
}
/*@Before("execution(* demo.testControllerEX.test(*)) && args(param)")
public void beforeSampleMethod(Object param) {
LOGGER.info("ASPECT" + param.getClass());
}*/
@Before("execution(demo.testControllerEX.new())")
public void constructor(JoinPoint point) {
LOGGER.info("ASPECT CONSTRUCTOR" + point.getThis().getClass().getAnnotation(Controller.class));
LOGGER.info("SERVICE" + testService);
}
@Around("execution(* demo.testControllerEX.testPrevent(*)) && args(param)")
public String prevent(ProceedingJoinPoint point, String param) throws Throwable{
//LOGGER.info("ASPECT AROUND" + param);
LOGGER.info("ASPECT AROUND " + testService);
String result = (String)point.proceed();
return result;
}
/*@DeclareParents(value="(demo.testControllerEX)",defaultImpl=testControllersssImpl.class)
private ITestControllerEX itestControllerEX;*/
}
Finally i'm try to apply my aspect to the constructor of a controller, it works but i need to applying when a profile is active, and another bug i find is that my testService is initialized after the constructor pointcut so it is null, but in the method testPrevent works obviously the service is initialized before, i can accept other form that accomplished what i want
EDIT
i got that my testService is loaded befome my constructor pointcut but remains null:
@Configuration
@ComponentScan(basePackages= {
"demo",
"demo.aspect"
})
@EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class Application {
@Autowired
private testService testService;
...
Unfortunately for you it's not going to be possible to achieve what you want to do. With pure Spring AOP there is no way to apply advice to constructor call so your only way is to use LTW (Load Time Weaving) with AspectJ.
Link to Spring AOP reference (Spring AOP capabilities and goals)
You may have already read about LTW to intercept your constructor call but your Aspect will not be a Spring Bean so you won't be able to inject your
TestService
. In the same way you are trying to set aProfile
to a non Spring Bean (as your advice is not going to be managed by Spring) so you won't be able make it active depending on you active spring profiles.By the way, using profiles in conjunction with Spring AOP is totally supported as long as you stay with spring managed aspects.
It would be interesting to know more about what you want to do, may be what you are trying to do is doable without using constructor call interceptor !