spring aop建议控制器失败

时间:2018-01-31 02:36:03

标签: spring-boot spring-aop

控制器:

@Slf4j
@Controller
@RequestMapping("rest/test/api")
public class TestApiController {

    private LogApiService logApiService;
    private LogApiController logApiController;
    public TestApiController(LogApiService las, LogApiController lac) {
        this.logApiService = las;
        this.logApiController = lac;
    }

    @RequestMapping(value="", produces = MediaType.APPLICATION_JSON_VALUE)
    private ResponseEntity config(@RequestBody LogConfigDTO dto) {
        return logApiController.config(dto);
    }

方面:

@Slf4j
@Component
@Aspect
public class TestApiControllerAop {

    private ApiProperties apiProperties;

    public TestApiControllerAop(ApiProperties apiProperties) {
        this.apiProperties = apiProperties;
    }

    @Before("execution(* com.demo.TestApiController.*(..)) " +
        "&& @annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void beforeRequestMappingAnnotatedMethod() {
        boolean isDebug = apiProperties.getLog().isDebug();
        log.info("debug flag is" + isDebug);
        if (!isDebug) {
            throw new RuntimeException("test api controller debug mode is turned off");
        }
    }
}

结果:bean应该注入但失败,LogApiServiceLogApiController个对象都为空。此外,@Before方法没有运行。虽然我可以看到TestApiController被标记为EnhancerBySpringCGLIB

1 个答案:

答案 0 :(得分:0)

问题是控制器中的私有访问级别!将其改为公开解决问题。 applicationContext.getBean(xx.class)将显示enter image description here

这正是它在pointcut目标方法为private时的解释:所有注入的字段都为空。我想这是因为当它是私有的时,控制器bean从与applicationContext.getBean()相同的位置取出,而当它是public时,控制器bean是不同的。我刚试过

@GetMapping("get")
private void get() {
    log.info("");
}

它不是切入点的目标,但它看起来与图片相同。控制器就像服务一样被调用,通常它是一种公共方法,就像一个规则。另一方面,也可以从浏览器调用控制器私有方法,使此规则“破坏”。结论是,无论方法是否有针对性,如果能够通过浏览器调用,它必须是公共方法。