Ответ
В Spring доступ к бину (управляемому компоненту) можно получить двумя основными способами:
1. Внедрение зависимости (Dependency Injection — DI)
Рекомендуемый подход. Контейнер IoC автоматически находит и внедряет зависимые бины.
- Через поле (field injection):
@Service public class OrderService { @Autowired // или @Inject private OrderRepository repository; } -
Через конструктор (constructor injection — предпочтительно):
@Service public class OrderService { private final OrderRepository repository; @Autowired // Необязательно в Spring 4.3+ public OrderService(OrderRepository repository) { this.repository = repository; } } -
Через сеттер (setter injection):
@Service public class OrderService { private OrderRepository repository; @Autowired public void setRepository(OrderRepository repository) { this.repository = repository; } }
2. Прямой доступ через ApplicationContext (не рекомендуется)
Явное получение бина из контекста. Нарушает принципы DI и усложняет тестирование.
@Component
public class MyComponent implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
public void someMethod() {
// Получение бина по типу
MyService service = context.getBean(MyService.class);
// Получение бина по имени и типу
MyService service = context.getBean("myService", MyService.class);
}
}
Итог: Всегда отдавайте предпочтение внедрению через конструктор, так как это обеспечивает неизменяемость зависимостей, упрощает модульное тестирование и делает код более стабильным.
Ответ 18+ 🔞
А, ну вот, опять про эти ваши бины, контейнеры и прочую хуйню. Слушай, давай я тебе на пальцах, а то ты, я смотрю, в этих дебрях запутаться можешь, как последний распиздяй.
Вот смотри, у тебя в Спринге есть этакая волшебная коробка — контекст. И там лежат все твои компоненты, которые ты наклепал. И чтобы их достать, есть два пути: как умный человек и как мудак.
Первый, правильный путь — внедрение зависимости. Это когда коробка сама тебе суёт нужную штуку в руки, ты только рот раскрой. Есть три способа, как она это делает:
- Через поле — по-быстрому, но некрасиво. Ты просто кричишь: «Эй, дай сюда!» и ставишь аннотацию. Просто, но потом тестировать — пиздец как неудобно.
@Service public class OrderService { @Autowired // или @Inject private OrderRepository repository; // Вот, взял и впендюрил прямо в поле } -
Через конструктор — это наш царь и бог, рекомендую. Ты говоришь: «Слушай, я без этого репозитория вообще нихуя не работаю, так что давай его сразу при рождении». Идеально, потому что зависимость теперь намертво, и подменить её в тестах — раз плюнуть.
@Service public class OrderService { private final OrderRepository repository; // @Autowired тут уже можно не писать, Спринг и так умный public OrderService(OrderRepository repository) { this.repository = repository; // Всё, приехали, теперь он твой } } -
Через сеттер — ну, на любителя. Типа «Можешь дать, а можешь и не дать, но если дашь — я его поставлю куда надо». Гибко, но опять же, не так надёжно, как конструктор.
@Service public class OrderService { private OrderRepository repository; @Autowired public void setRepository(OrderRepository repository) { this.repository = repository; // Подошел, положил, ушел } }
А теперь второй путь — для отчаянных или для тех, кому доверия ебать ноль. Прямой лезть в контекст и шарить там руками. Делать так — это всё равно что в гостях самому лезть в холодильник хозяина. Вроде можно, но выглядит как последняя манда с ушами.
@Component
public class MyComponent implements ApplicationContextAware {
private ApplicationContext context; // Придержал контекст за жопу
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
public void someMethod() {
// И теперь в любой момент лезу и выковыриваю
MyService service = context.getBean(MyService.class);
// Или вот так, по имени, если их несколько
MyService service = context.getBean("myService", MyService.class);
}
}
Итог, блядь, простой как три копейки: забей хуй на ApplicationContext в коде. Твой лучший друг — это внедрение через конструктор. Всё будет жёстко, понятно, и тесты писать — одно удовольствие, а не ебаться как сука с граблями. Всё, вопрос закрыт.