在@Aspect中使用Spring @Profile

7
所需的是在特定配置文件激活时将Spring Aspect应用于我的类,但我找不到解决方案。我尝试了http://city81.blogspot.com/2012/05/using-spring-profile-with.html中提出的方法,但这种方法已经过时并且在我的情况下无法工作。我有一个用于测试的Spring启动项目,并根据链接执行以下操作:

配置应用程序:

@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);
    }
}

我的方面:

//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;*/
}

最后,我尝试将我的方面应用于控制器的构造函数,它可以工作,但我需要在配置文件处于活动状态时应用。我发现另一个错误是,我的testService在构造函数切入点之后初始化,因此为null,但在testPrevent方法中显然在初始化服务之前就已经初始化了。我可以接受其他形式来实现我的需求。
编辑:
我发现我的testService在构造函数切入点之前加载,但仍然为空。
@Configuration
    @ComponentScan(basePackages= {
            "demo",
            "demo.aspect"
    })
    @EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
    @EnableAspectJAutoProxy(proxyTargetClass=true)
    public class Application {

    @Autowired
    private testService testService;
    ...

将@Profile("asdasd")添加到TestAspect类中,并删除testAspect @Bean方法。 - jax
1个回答

1
很遗憾,你想要做的事情是不可能实现的。使用纯Spring AOP无法对构造函数调用应用advice,所以你唯一的方法是使用LTW(Load Time Weaving)与AspectJ。 Spring AOP参考链接(Spring AOP能力和目标) Spring AOP目前仅支持方法执行连接点(在Spring bean上通知方法执行)。
你可能已经了解了如何使用LTW拦截你的构造函数调用,但你的Aspect不会成为Spring Bean,因此你将无法注入你的TestService。同样,你正在尝试为非Spring Bean设置Profile(因为你的advice不会被Spring管理),因此你将无法根据活动的Spring配置文件使其处于活动状态。
顺便说一下,在与Spring AOP结合使用时,使用配置文件是完全受支持的,只要你保持Spring管理的方面。
更多了解你想要做什么将会很有趣,也许你正在尝试的事情可以在不使用构造函数调用拦截器的情况下完成!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接