Это проблема с ногами робота . Решение состоит в том, чтобы использовать PrivateModule s для привязки каждого дерева зависимостей и выставлять только корень этого дерева. Есть несколько способов сделать это, но вот пример того, как вы обычно это делаете (в зависимости от ваших потребностей есть много вариантов):
public class ClientModule расширяет PrivateModule {private final Writer writer; частный конечный класс & lt ;? расширяет аннотацию & gt; annotationType; public ClientModule (писатель писателя, класс & lt ;? extends Annotation & gt; annotationType) {this.writer = writer; this.annotationType = annotationType; } @Override protected void configure () {bind (Writer.class) .toInstance (writer); связывания (Logger.class) .to (LoggerImpl.class); выставить (Client.class) .annotatedWith (annotationType); }} Открытый класс ClientFactoryModule расширяет AbstractModule {private final File file; public ClientFactoryModule (Файл файла) {this.file = file; } @Override protected void configure () {install (новый ClientModule (новый StdOutWriter (), StdOut.class)); install (новый ClientModule (новый FileWriter (файл), FileOut.class)); связывания (ClientFactory.class) .to (ClientFactoryImpl.class); }} Открытый класс ClientFactoryImpl реализует ClientFactory {private final Client stdOutClient; закрытый конечный клиентский файл клиента; @Inject public ClientFactoryImpl (@StdOut Client stdOutClient, @FileOut Client fileClient) {this.stdOutClient = stdOutClient; this.fileClient = fileClient; } ...}
Ваш сценарий метода Клиентский файлClient (File)
довольно немного отличается.
- @Controller public class LoginController { --code-- } - @Configuration public class AppConfig { @Bean public SessionFactory sessionFactory() {--code-- }
Оба подхода нацелены на регистрацию целевого типа в контейнере Spring.
Разница заключается в том, что @Bean
применим к методам, тогда как @Component
применим к типам.
когда вы используете аннотацию @Bean
, вы управляете логикой создания экземпляра в теле метода (см. пример выше ). С аннотацией @Component
вы не можете.
@Bean
и @Component
обратитесь к исходному коду - & gt; Значение @Target
– Bharat
10 October 2017 в 09:17
Давайте рассмотрим, что я хочу конкретной реализации в зависимости от некоторого динамического состояния. @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
.
@Component Предпочтительно для сканирования компонентов и автоматической проводки.
Когда вы должны использовать @Bean?
Иногда автоматическая настройка не является опцией. Когда? Представим себе, что вы хотите подключать компоненты из сторонних библиотек (у вас нет исходного кода, поэтому вы не можете комментировать его классы с помощью @Component), поэтому автоматическая настройка невозможна.
Аннотации @Bean возвращают объект, который весна должна регистрироваться как компонент в контексте приложения. Тело метода несет логику, ответственную за создание экземпляра.
@Component
и @Bean
выполняют две совершенно разные вещи, и их не следует путать.
@Component
(и @Service
и @Repository
) используются для автоматического обнаружения и автоматическое конфигурирование bean-компонентов, использующее сканирование классов. Существует неявное взаимно однозначное сопоставление между аннотированным классом и компонентом (т. Е. Одним компонентом для каждого класса). [7]
@Bean
используется для явно , объявляет один бит, вместо того, чтобы позволить Spring делать это автоматически, как указано выше. явно ограничено этим подходом, поскольку это чисто декларативный. , Он отделяет декларацию компонента от определения класса и позволяет вам создавать и настраивать компоненты точно так, как вы выберете.
Чтобы ответить на ваш вопрос ...
было возможно повторно использовать аннотацию
blockquote>@Component
вместо введения аннотации@Bean
?Конечно, возможно; но они решили не делать этого, так как они совершенно разные. Весна уже довольно запутанная, не загрязняя воды дальше.
@Component
только когда требуется автоуправление? Кажется, @Bean
не может повлиять на @Autowired
– Jaskey
18 November 2015 в 13:00
@Autowired
с @Bean
, если вы аннотировали свой класс bean с помощью @Configuration
– starcorn
4 March 2016 в 10:53
Когда вы используете тег @Component
, это то же самое, что и POJO (обычный статический объект Java) с помощью метода объявления ванильных компонентов (аннотируется с @Bean
). Например, следующий метод 1 и 2 даст тот же результат.
Метод 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);
}
Способ 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 позволяет вам сохранять объявления бобов вместе, это немного более гибкий и т. д. Вы можете даже хотите добавить еще не Vanilla SomeClass bean, как показано ниже:
@Bean
SomeClass strawberryClass(){
return new SomeClass(new Integer(1));
}