@Autowire возвращает ноль после добавления Spring AOP - PullRequest
0 голосов
/ 15 апреля 2019

После добавления 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:

@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) {
    }
}

Как только я удаляю аспект, все работает отлично.Есть идеи, что мне здесь не хватает?

1 Ответ

2 голосов
/ 16 апреля 2019

Spring AOP по умолчанию работает с использованием прокси. В этом случае используется прокси на основе класса, потому что интерфейс не был реализован. Прокси на основе классов расширяет фактический класс и переопределяет все методы для применения перехватчиков / аспектов.

Однако метод private не может быть переопределен в подклассе, и поэтому ваш метод контроллера будет вызываться на прокси вместо проксируемого объекта. В прокси никогда не вводится ничего, поэтому в поле aService всегда указывается null.

Чтобы исправить, сделайте метод public или protected, чтобы подкласс мог переопределять метод, и в конечном итоге метод будет вызываться на проксируемом экземпляре вместо прокси.

...