Вопрос по spring, java – Весна: @Component против @Bean

292

Я это понимаю@Component Весной 2.5 была введена аннотация, чтобы избавиться от определения bean-компонента XML с помощью сканирования пути к классам.

@Bean был введен весной 3.0 и может быть использован с@Configuration чтобы полностью избавиться от XML-файла и использовать вместо него конфигурацию Java.

Было бы возможно повторно использовать@Component аннотация вместо введения@Bean аннотаций? Насколько я понимаю, конечной целью является создание бобов в обоих случаях.

Есть ли где-нибудь, где @Bean можно использовать отдельно от класса Configuration? Willa
Смотрите такжеWhat's the difference between @Component, @Repository & @Service annotations in Spring? Martin Schröder
Я суммирую это, говоря о методе с@bean возвращает настраиваемый экземпляр Spring Bean, в то время как@component определяет класс, который при необходимости может быть создан экземпляром Spring IoC. Sebas
@ Вилла Да, есть. Это называетсяLite mode, И это не рекомендуется. Посмотреть здесь:docs.spring.io/spring/docs/current/spring-framework-reference/… smwikipedia

Ваш Ответ

9   ответов
39
@Component auto detects and configures the beans using classpath scanning whereas @Bean explicitly declares a single bean, rather than letting Spring do it automatically. @Component does not decouple the declaration of the bean from the class definition where as @Bean decouples the declaration of the bean from the class definition. @Component is a class level annotation where as @Bean is a method level annotation and name of the method serves as the bean name. @Component need not to be used with the @Configuration annotation where as @Bean annotation has to be used within the class which is annotated with @Configuration. We cannot create a bean of a class using @Component, if the class is outside spring container whereas we can create a bean of a class using @Bean even if the class is present outside the spring container. @Component has different specializations like @Controller, @Repository and @Service whereas @Bean has no specializations.
Error: User Rate Limit Exceeded
220

@Component чения.

When should you use @Bean?

Иногда автоматическая настройка не вариант.When? Давайте представим, что вы хотите соединить компоненты из сторонних библиотек (у вас нет исходного кода, поэтому вы не можете аннотировать его классы с помощью @Component), поэтому автоматическая настройка невозможна.

@Bean аннотированиеreturns an object та весна должна регистрироваться как боб в контексте приложения.body of the method несет логику, ответственную за создание экземпляра.

Error: User Rate Limit Exceeded@ComponentError: User Rate Limit Exceeded@BeanError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3
@component and its specializations(@Controller, @service, @repository) allow for auto-detection using classpath scanning. If we see component class like @Controller, @service, @repository will be scan automatically by the spring framework using the component scan. @Bean on the other hand can only be used to explicitly declare a single bean in a configuration class. @Bean used to explicitly declare a single bean, rather than letting spring do it automatically. Its make septate declaration of bean from the class definition. In short @Controller, @service, @repository are for auto-detection and @Bean to create seprate bean from class
    - @Controller
    public class LoginController 
    { --code-- }

    - @Configuration
    public class AppConfig {
    @Bean
    public SessionFactory sessionFactory() 
    {--code-- }
139

что я хочу конкретную реализацию в зависимости от некоторого динамического состояния. @Bean идеально подходит для этого случая.

@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
    case 1:
        return new Impl1();
    case 2:
        return new Impl2();
    case 3:
        return new Impl3();
    default:
        return new Impl();
    }
}

Однако нет никакого способа сделать это с@Component.

Error: User Rate Limit Exceeded
1

  Одним из них является создание класса с аннотацией@Component. The other is to create a method and annotate it with @Bean, Для тех классов, которые содержат метод с@Bean должен быть аннотирован@Configuration   Как только вы запустите свой весенний проект, класс с@ComponentScan аннотация будет сканировать каждый класс с@Component и восстановите экземпляр этого класса в контейнере Ioc. Другое дело@ComponentScan будет делать это с помощью методов с@Bean и восстановите возвращаемый объект в контейнере Ioc в виде компонента.  Поэтому, когда вам нужно решить, какой тип бобов вы хотите создать в зависимости от текущих состояний, вам нужно использовать@Bean, Вы можете написать логику и вернуть нужный объект.  Также стоит упомянуть название метода с@Bean это имя бина по умолчанию.

17

@Component которая может быть применена к любому классу приложения, чтобы сделать его компонентом, управляемым пружиной (проще говоря, универсальный стереотип для любого компонента, управляемого пружиной). когда путь к классу сканируется компонентным сканированием пружины(@ComponentScan) особенность, это идентифицирует классы, отмеченные@Component аннотации (в рамках данного пакета) и создать бины таких классов и зарегистрировать их в ApplicationContext.@Component является аннотацией на уровне класса, и ее целью является сделать класс компонентом с пружинным управлением и автоматически определяемым компонентом для функции сканирования пути к классам.

если вы хотите узнать больше о@Component и другие стереотипные аннотации, рекомендуется посмотреть в этой статье.

@Bean используется для явного объявления и регистрации bean-компонента (как bean-компонента конфигурации) в контейнере Spring IOC, который возвращается из метода. @Bean - это аннотация уровня метода, которая используется внутри класса, помеченного как@Configuration, Просто@Bean аннотация используется для регистрации компонента, возвращаемого методом, в качестве компонента конфигурации пружины в контейнере IOC.@Bean является только аннотацией уровня метода и не может использоваться с классами и объявлением объекта.

@Bean аннотация указывает, что метод создает компонент, которым должен управлять контейнер Spring.

Чтобы объявить бин, просто аннотируйте метод с помощью@Bean аннотаций. Когда JavaConfig встречает такой метод, он выполняет этот метод и регистрирует возвращаемое значение как компонент в ApplicationContext. По умолчанию имя компонента будет таким же, как имя метода. Ниже приведен простой пример объявления метода @Bean.

@Configuration
public class ApplicationConfig {

    @Bean
    public User adminUserProfile() {
        return new User("Rami","Nassar");
    }
}

В классе ApplicationConfig вы можете видеть, что мы сначала используем@Configuration аннотация для информирования Spring о том, что это файл конфигурации на основе Java. После этого@Bean аннотация используется для объявления bean-компонента Spring и требований DI. @Bean аннотация эквивалентна тэг, имя метода эквивалентно атрибуту id внутри тег. Я надеюсь, что после прочтения этой статьи у вас есть четкое представление о реальной цели и использовании@Bean а также@Component аннотаций.

Error: User Rate Limit Exceeded
314

@Component а также@Bean делать две совершенно разные вещи, и не следует путать.

@Component (а также@Service а также@Repository) используются для автоматического обнаружения и автоматической настройки bean-компонентов с использованием сканирования пути к классам. Существует неявное взаимно-однозначное сопоставление между аннотированным классом и компонентом (т.е. одним компонентом на класс). Управление проводкой при этом подходе весьма ограничено, поскольку оно является чисто декларативным.

@Bean используется дляexplicitly объявите один компонент, вместо того чтобы позволить Spring делать это автоматически, как указано выше. Он отделяет объявление bean-компонента от определения класса и позволяет вам создавать и настраивать bean-компоненты именно так, как вы выберете.

Чтобы ответить на ваш вопрос ...

would it have been possible to re-use the @Component annotation instead of introducing @Bean annotation?

Конечно, наверное; но они решили не делать этого, так как они совершенно разные. Весна уже достаточно запутана, не пачкая воды дальше.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded@AutowiredError: User Rate Limit Exceeded@BeanError: User Rate Limit Exceeded@Configuration
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded@ComponentError: User Rate Limit Exceeded@BeanError: User Rate Limit Exceeded@Autowired
Error: User Rate Limit Exceeded
62

g.

Разница в том, что@Bean применимо кmethods, в то время как@Component применимо кtypes.

Поэтому, когда вы используете@Bean аннотация, которой вы управляете в логике создания экземпляра в теле метода (см.пример выше). С@Component аннотации вы не можете.

10

@Component тег, это то же самое, что наличие POJO (Plain Old Java Object) с методом объявления ванильного компонента (с аннотацией@Bean). Например, следующий метод 1 и 2 даст тот же результат.

Method 1

@Component
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

с бобом для "числа":

@Bean
Integer theNumber(){
    return new Integer(3456);
}

Method 2

//Note: no @Component tag
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

с бобами для обоих:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

@Bean
SomeClass someClass(Integer theNumber){
    return new SomeClass(theNumber);
}

Способ 2 позволяет вам сохранять объявления bean-компонентов вместе, он немного более гибок и т. Д. Вы можете даже захотеть добавить другой не-vanilla bean-компонент SomeClass, как показано ниже:

@Bean
SomeClass strawberryClass(){
    return new SomeClass(new Integer(1));
}

Похожие вопросы