@Autowire возвращает null после добавления Spring AOP

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

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

Вы используете @EnableAspectJAutoProxy?

Nikolas Charalambidis 15.04.2019 11:49

@Nikolas Да, я только что добавил свою конфигурацию.

Carrier Pigeon Protocol 15.04.2019 11:54

Сделайте метод public иначе он не сработает. Вместо того, чтобы передавать вызов метода проксируемому объекту, теперь он вызывается на самом прокси, который не имеет связанных полей. Где, как у обернутого объекта, и вы хотите передать ему вызов метода. Следовательно, сделайте метод public.

M. Deinum 15.04.2019 12:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
500
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

Другие вопросы по теме