在@Aspect中使用Spring @Profile

Die*_*nci 6 java spring aspectj spring-aop spring-boot

所以我想要的是在配置文件处于活动状态时将特定的Spring Aspect应用于我的类,但我找不到解决方案,我尝试在http://city81.blogspot.com/2012/05/中使用的方法-spring-profile-with.html但很老,在我的情况下不起作用,我有一个Spring Started项目进行测试,我根据链接执行以下操作:

配置应用程序:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的看点:

//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;*/
}
Run Code Online (Sandbox Code Playgroud)

最后我尝试将我的方面应用于控制器的构造函数,它可以工作,但我需要在配置文件处于活动状态时应用,而我发现的另一个错误是我的testService在构造函数切入点后初始化,因此它为null,但是在方法testPrevent显然服务初始化之前,我可以接受其他形式完成我想要的

编辑

我得到了我的testService加载befome我的构造函数切入点但仍保持为null:

@Configuration
    @ComponentScan(basePackages= {
            "demo",
            "demo.aspect"
    })
    @EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
    @EnableAspectJAutoProxy(proxyTargetClass=true)
    public class Application {

    @Autowired
    private testService testService;
    ...
Run Code Online (Sandbox Code Playgroud)

Ale*_*cob 1

对你来说不幸的是,你不可能实现你想做的事情。对于纯 Spring AOP,无法将建议应用于构造函数调用,因此唯一的方法是将 LTW(加载时编织)与 AspectJ 结合使用。

Spring AOP 参考链接(Spring AOP 功能和目标)

Spring AOP 当前仅支持方法执行连接点(建议在 Spring bean 上执行方法)。

您可能已经阅读过有关 LTW 来拦截构造函数调用的信息,但您的 Aspect 不是 Spring Bean,因此您将无法注入TestService. 以同样的方式,您尝试将 a 设置Profile为非 Spring Bean(因为您的建议不会由 Spring 管理),因此您将无法根据您活动的 spring 配置文件使其处于活动状态。

顺便说一句,只要您继续使用 Spring 管理的方面,就完全支持将配置文件与 Spring AOP 结合使用。

了解更多关于您想要做什么会很有趣,也许您想要做的事情在不使用构造函数调用拦截器的情况下也是可行的!