简体   繁体   English

在添加Spring AOP之后@Autowire返回null

[英]@Autowire returns null after adding Spring AOP

After adding Spring AOP to my Spring Boot project, the following aspect produces a NullPointerException on an autowired service component in my controllers: 将Spring AOP添加到我的Spring Boot项目中之后,以下方面将在控制器中的自动装配服务组件上生成NullPointerException:

@Aspect
@Component
@Slf4j
public class LogRequestAspect {

    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping) && execution(public * *(..))")
    public Object log(final ProceedingJoinPoint joinPoint) throws Throwable {
        final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .currentRequestAttributes())
                .getRequest();

        final Object proceed = joinPoint.proceed();
            log.info(
                    "{} {} from {},{}",
                    request.getMethod(),
                    request.getRequestURI(),
                    request.getRemoteAddr(),
                    request.getHeader("X-Forwarded-For"));

        return proceed;
    }
}

Example controller: 控制器示例:

@RestController
public class AController {

    @Autowired
    AService aService;

    @RequestMapping("/doSomething")
    private List<Map<String, Object>> doSomething() {
        return aService.doSomething();
    }
}

Example service: 服务示例:

@Service
public class AService {
    public List<Map<String, Object>> doSomething() {
        List<Map<String, Object>> results = new ArrayList<>();
        return results;
    }
}

Example configuration: 配置示例:

@EnableAspectJAutoProxy
@SpringBootApplication
public class Application implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... strings) {
    }
}

As soon as i remove the aspect, everything works perfectly. 我删除该方面后,一切都会正常运行。 Any idea what i'm missing here? 知道我在这里缺少什么吗?

Spring AOP, by default, works using proxies. 默认情况下,Spring AOP使用代理工作。 IN this case a class based proxy is being used because no interface has been implemented. 在这种情况下,将使用基于类的代理,因为尚未实现任何接口。 A class based proxy extends the actual class and overrides all the methods to apply the interceptors/aspects. 基于类的代理扩展了实际的类,并覆盖了所有应用拦截器/方面的方法。

However a private method cannot be overriden in a subclass and as such your controller method will be invoked on the proxy instead of the proxied object. 但是, private方法不能在子类中覆盖,因此,控制器方法将在代理而不是代理对象上调用。 The proxy never has anything injected and hence the aService field is always null on there. 代理永远不会注入任何东西,因此aService字段始终为null

To fix make the method public or protected so that a subclass can override the method and eventually the method will be called on the proxied instance instead of the proxy. 要修复此问题,请将该方法publicprotected以使子类可以覆盖该方法,并最终在代理实例(而不是代理)上调用该方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM