Все 3 примера имеют одинаковый эффект. Есть только некоторые нюансы, и, в конце концов, это вопрос стиля.
В первом примере - Spring сканирует компоненты, реализующие определенные интерфейсы маркеров, ApplicationContextAware
является одним из них, и выполняет метод интерфейса с фактическим экземпляром applicationContext, предоставленным в параметре во время выполнения DI.
Второй пример работает только в Spring 4.3 и выше. Когда у вашего компонента есть единственный конструктор, который определяет его зависимости, тогда внедрение зависимостей через конструктор предполагается даже без аннотаций.
Третий - это просто простое внедрение с помощью аннотации @Autowired
.
Нет простого ответа, какой путь лучше. Документация для интерфейса ApplicationContextAware
даже предполагает, что вам может быть лучше с другими способами, если вам нужен applicationContext только для поиска бина (например, когда вам нужно использовать метод внедрения метода).
Подводя итог: выбор между 1-е, 2-е и 3-е - это просто выбор между различными вариантами IoC / DI, а также, если пропустить необязательную аннотацию @Autowired
или нет.
PS
ваши 2-й и 3-й примеры не нужно реализовывать ApplicationContextAware
интерфейс вообще. Фактически компилятор будет жаловаться, что вы не предоставляете установщик для ApplicationContect
объекта.