在@Aspect中使用Spring @Profile

时间:2014-08-14 14:18:48

标签: java spring aspectj spring-aop spring-boot

所以我想要的是在个人资料处于活动状态时将特定的Spring Aspect应用到我的课程中,但我找不到解决方案,我尝试http://city81.blogspot.com/2012/05/using-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);
    }
}

我的观点:

//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已经加载了我的构造函数切入点但仍然是null:

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

    @Autowired
    private testService testService;
    ...

1 个答案:

答案 0 :(得分:1)

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

Link to Spring AOP reference (Spring AOP capabilities and goals)

  

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

您可能已经阅读过LTW来拦截您的构造函数调用,但您的Aspect不会是Spring Bean,因此您无法注入TestService。以同样的方式,您尝试将Profile设置为非Spring Bean(因为您的建议不会由Spring管理),因此根据您的活动弹簧,您无法将其设置为活动状态轮廓。

顺便说一下,只要你坚持使用Spring管理方面,就可以完全支持将配置文件与Spring AOP结合使用。

了解更多关于你想做什么会很有趣,如果不使用构造函数调用拦截器,你可能会做的事情是可行的!