【问题标题】:using Spring @Profile in @Aspect在@Aspect 中使用Spring @Profile
【发布时间】:2014-08-14 14:18:48
【问题描述】:

所以我想要的是在配置文件处于活动状态时将特定的 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 在我的构造函数切入点之前加载但仍然为空:

@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 方法。

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


【解决方案1】:

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

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 结合使用。

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

【讨论】:

    猜你喜欢
    • 2015-09-25
    • 2014-10-15
    • 2019-10-10
    • 1970-01-01
    • 2014-02-10
    • 2013-10-14
    • 2011-04-28
    • 2018-03-09
    • 2021-04-26
    相关资源
    最近更新 更多