SpringBoot MethodInterceptor自动代理

时间:2017-07-23 16:54:04

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

如何在SpringBoot中使用 MethodInterceptor 拦截 @RestController 方法?

在使用springboot之前,我有一个简单的Interceptor,它记录bean方法的执行时间。只需通过默认代理定义拦截所有spring bean方法。

@Component
public class MethodTimer implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    final StopWatch stopWatch = new StopWatch();
    stopWatch.start(methodInvocation.getMethod().toGenericString());
    try {
        return methodInvocation.proceed();
    }
    finally {
        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
    }
  }
}

弹簧配置 com.mypackages 包含bean和MethodInterceptor实现。

<context:component-scan base-package="com.mypackages" />
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
  <property name="proxyTargetClass" value="true"/>
</bean>

上面的配置是通过

加载的
@ContextConfiguration("/application-context.xml")

记录方法执行,一切似乎都有效,生活也很好。

转移到SpringBoot

我使用相同的代码,切换到注释(消除* .xml)配置

@SpringBootApplication(scanBasePackages = { "com.mypackages" })
@EnableAutoConfiguration
@EnableAspectJAutoProxy(proxyTargetClass=true)

使用System.out.println()为MethodTimer添加了一个构造函数,以确保Spring引导加载了Interceptor

public MethodTimer() {
  System.out.println("MethodTimer - Constructor");
}

是的,它被加载并创建为“MethodTimer - Constructor”在控制台日志中找到。

但是,没有任何@RestController方法被截获。下面是一个简单的Rest Controller

@RestController
@RequestMapping("/test")
public class HelloWorldService {
  @RequestMapping(method = RequestMethod.GET)
  public String sayHello() {
    System.out.println("Hello World!");
    return "Hello World!";
  }
}

甚至尝试通过 @Component @Autowired @RestController 中创建一个纯粹的spring bean,看看那个纯粹的spring bean是不是截获,但也没有截获。

一个简单的测试服务bean。应拦截test()方法。

@Component
public class TestService {
  public void test() {
    System.out.println("TestService.test()");
  }
}

修改了RestController

@RestController
@RequestMapping("/test")
public class HelloWorldService {
  @Autowired
  private TestService testService;

  @RequestMapping(method = RequestMethod.GET)
  public String sayHello() {
    testService.test();
    return "Hello World!";
  }
}

注释

  1. MethodTimer 在调用构造函数时加载,在控制台中显示System.out.println日志,但是看起来spring boot并没有自动确定这个bean /组件正在实现的MethodInterceptor
  2. 使用 @Component bean注释的简单Spring Bean未被截获。
  3. 未使用 @RestController 注释的Rest控制器被截获。
  4. 我尝试在RestController中添加 @Component @Service ,但它无效。
  5. 我尝试过 @EnableAutoConfiguration ,在 application.properties 中添加 spring.aop。* 配置,但无效。
  6. 尝试使用SpringBoot版本 1.5.4.RELEASE ,不起作用。
  7. 我知道我总是可以尝试使用Aspect,如spring-boot-sample-aop示例所示:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-aop

    但是无法使用以前的spring代码并使用springboot配置它太蹩脚了。如果在spring boot中不再支持 MethodInterceptor DefaultAdvisorAutoProxyCreator ,那么它应该已被弃用

0 个答案:

没有答案