首页 > 解决方案 > @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) {
    }
}

一旦我删除了方面,一切都会完美运行。知道我在这里缺少什么吗?

标签: javaspringspring-bootaopspring-aop

解决方案


Spring AOP 默认使用代理。在这种情况下,由于没有实现接口,因此使用了基于类的代理。基于类的代理扩展实际类并覆盖所有方法以应用拦截器/方面。

但是,private不能在子类中覆盖方法,因此您的控制器方法将在代理而不是代理对象上调用。代理从来没有注入任何东西,因此该aService字段总是null在那里。

要修复该方法publicprotected以便子类可以覆盖该方法,最终该方法将在代理实例而不是代理上调用。


推荐阅读