Разница между @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).