java - @Autowire 添加 Spring AOP 后返回 null
问题描述
将 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;
}
}
示例控制器:
@RestController
public class AController {
@Autowired
AService aService;
@RequestMapping("/doSomething")
private List<Map<String, Object>> doSomething() {
return aService.doSomething();
}
}
示例服务:
@Service
public class AService {
public List<Map<String, Object>> doSomething() {
List<Map<String, Object>> results = new ArrayList<>();
return results;
}
}
示例配置:
@EnableAspectJAutoProxy
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) {
}
}
一旦我删除了方面,一切都会完美运行。知道我在这里缺少什么吗?
解决方案
Spring AOP 默认使用代理。在这种情况下,由于没有实现接口,因此使用了基于类的代理。基于类的代理扩展实际类并覆盖所有方法以应用拦截器/方面。
但是,private
不能在子类中覆盖方法,因此您的控制器方法将在代理而不是代理对象上调用。代理从来没有注入任何东西,因此该aService
字段总是null
在那里。
要修复该方法public
,protected
以便子类可以覆盖该方法,最终该方法将在代理实例而不是代理上调用。
推荐阅读
- angular - 打开模态时出现未定义的错误打开
- vim - 命令模式下的 vim 路径补全
- ruby - Logstash 使用 grok 和 ruby 提取和自定义字段
- javafx - 如何调用绑定属性的方法
- ios - iTunes 商店操作失败。从 Xcode 9.3 在 TestFlight 上上传构建时出现 WatchKit 错误
- javascript - 如何在 html5 画布中围绕多个形状绘制一个框
- swift - 下载后如何修复 UIImageView Aspect Fit
- mongodb - Mongodb 将多个集合的查找聚合到一个嵌套输出
- c++ - 如何增加我的“for循环”呈现的结果?
- ios - 来自alamofire swift3的失败响应