Разница между @Bean и @Autowired
Почему я не могу использовать @Autowired
в этом случае?
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
но может использовать @Bean
@SpringBootApplication
public class Application {
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
BookingService bookingService = ctx.getBean(BookingService.class);
bookingService.book("Alice", "Bob", "Carol");
}
}
Не два способа генерировать BookingService
одно и то же?
Ответы
Ответ 1
@Bean
и @Autowired
выполняют две очень разные вещи. Другие ответы здесь объясняются немного подробнее, но на более простом уровне:
-
@Bean
сообщает Spring 'вот экземпляр этого класса, пожалуйста, держите его в руках и верните мне, когда я спрошу.
-
@Autowired
говорит: "Пожалуйста, дайте мне экземпляр этого класса, например, тот, который я создал с помощью аннотации @Bean
ранее".
Это имеет смысл? В первом примере вы запрашиваете Spring, чтобы предоставить вам экземпляр BookingService
, но вы никогда его не создаете, поэтому Spring не может ничего вам дать. Во втором примере вы создаете новый экземпляр BookingService
, рассказывая об этом Spring, а затем в методе main()
, запрашивая его.
Если вы хотите, вы можете удалить две дополнительные строки из второго метода main()
и объединить два примера, как показано ниже:
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
В этом случае аннотация @Bean
дает Spring BookingService
, а @Autowired
использует ее.
Это был бы немного бессмысленный пример, поскольку вы используете его все в одном классе, но он становится полезным, если у вас есть @Bean
, определенный в одном классе, а @Autowired
- в другом.
Ответ 2
@Bean
BookingService bookingService() {
return new BookingService();
}
@Bean
регистрирует службу только как компонент (вид Object) в контексте приложения Spring. Проще говоря, это просто регистрация и больше ничего.
@Autowired
BookingService bookingService;
При @Autowired
переменной с помощью @Autowired
вставляется компонент BookingService
(т. BookingService
Object) из контекста приложения Spring.
(т.е.) Зарегистрированный бин с аннотацией @Bean
будет @Bean
в переменную, аннотированную @Autowired
.
Надеюсь, это очистит ваши сомнения!
Ответ 3
отличный ответ от @DaveyDaveDave
В примере вместо
@Bean
BookingService bookingService() {
return new BookingService();
}
Вы можете использовать аннотацию @Service для класса BookingService
Ответ 4
Вот хорошая статья о аннотации @Autowired: http://www.baeldung.com/spring-autowire
Аннотация @Autowired может создавать экземпляры ваших инъекций, определяя @ComponentScan ("namespace.with.your.components.for.inject") в классе конфигурации
@Configuration
@ComponentScan("com.baeldung.autowire.sample")
public class AppConfig {}
Все компоненты должны быть помечены аннотацией @Component. Он заменяет аннотацию @Bean.
Ответ 5
@Bean - это просто определение метаданных для создания компонента (эквивалент тега). @Autowired - внедрить зависимость в bean-компонент (эквивалентно тегу/атрибуту ref XML).