【问题标题】:AOP with Spring Boot Advice Not Triggering带有 Spring Boot Advice 的 AOP 未触发
【发布时间】:2016-05-13 03:29:26
【问题描述】:

使用:Spring Boot :: (v1.2.8.RELEASE)

我已经在 build.gradle 中使用 aop starter 设置了一个 Spring Boot 应用程序

compile("org.springframework.boot:spring-boot-starter-aop")

我已经检查并获得了依赖项:

|    |    |    |         +--- org.springframework:spring-aop:4.1.9.RELEASE
|    |    |    |         |    +--- aopalliance:aopalliance:1.0

这是 AspectConfig:

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class AspectConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

我已将 Configuration 类放在应用程序层次结构的基础上,以便组件扫描仅覆盖整个应用程序。这都是原型代码,但它最终会成为启动模块的一部分,扫描所有区域的能力会很有帮助。

现在我定义了一个注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AutowiredRestTemplate {
    String name();
    String methodUrl();
}

并且有一个测试方法:

@Component(value = "testGateway")
public class TestGatewayImpl implements TestGateway {
    private static final Logger LOG = LoggerFactory.getLogger(TestGatewayImpl.class);

    AuspostRestTemplate restTemplate;

    @AutowiredRestTemplate(name = "locations", methodUrl = "/fishing")
    public Response doWork() {
        LOG.debug("Got into gateway with restTemplate {}", restTemplate);
        return restTemplate.getForObject(Response.class);
    }
}

现在是建议:

@Aspect
@Component
public class AutowiredRestTemplateAspect {

    @Autowired
    Map<String, AuspostRestTemplate> restTemplateMap;

    @Autowired
    private ApplicationContext context;

    @Pointcut("execution(public * *(..))")
    public void anyPublicMethod(){}

    @Around("anyPublicMethod() && @annotation(autowiredRestTemplate)")
    public Object inAnyMethod(ProceedingJoinPoint pjp, AutowiredRestTemplate autowiredRestTemplate) throws Throwable{

        AuspostRestTemplate restTemplate = restTemplateMap.get(autowiredRestTemplate.name());
        restTemplate.setMethodUrl(autowiredRestTemplate.methodUrl());
            pjp.getTarget().getClass().getDeclaredField("restTemplate").set(pjp.getTarget(),restTemplate);
        return pjp.proceed();

    }
}

问题是当doWork() 方法运行时,Advice 永远不会被触发。甚至从日志中看起来好像甚至没有设置切入点。谁能看出这里出了什么问题?

编辑:我已经为我想要使用的注释添加了配置以及保留和目标注释(在这个问题的上方)。 EDIT2:更改了 Configuration 类上的 ComponentScan,因为另一件事很复杂并且无论如何都不起作用。

【问题讨论】:

  • 这是你的全部注释吗?
  • 你也知道你正在做的事情有潜在的危险吗?一个模板可以在多个请求中覆盖另一个模板。
  • 哦,我想我应该包括所有设置 requestTemplates 映射的配置。没有任何内容被覆盖,只是从地图中选择了不同的 requestTemplates(在应用程序启动时加载)。我只是没有包括所有这些东西,因为它似乎与问题无关
  • 仍然有一个特定名称的实例。现在,如果您有多个线程需要该单个实例,那么您正在更改一个已经在使用的线程......这无关紧要,只是想指出这一点。正如我在第一条评论中提到的那样,您的整个注释以及您是否还可以添加您正在使用的 Spring Boot 版本。
  • Spring Boot 1.2.8。 Java 8。是的,它是整个注释。我的印象是 Runtime 是默认的 RetentionPolicy 而 Target 是默认的一切。我确实尝试设置两者(包括@Target({ElementType.METHOD}),但没有任何区别。所以,是的,这就是整个注释。

标签: java spring spring-boot annotations aop


【解决方案1】:

您是否尝试将@EnableAspectJAutoProxy(proxyTargetClass=true) 放在您的配置类中?

【讨论】:

  • 是的,我做到了。我刚刚将 Config 类添加到问题中,因为它似乎非常相关。
  • 这解决了我的问题 - 谢谢 Jakub!
猜你喜欢
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多