2015-05-07 3 views
0

Я просто изучаю весну, и что-то поразило меня как очень странное относительно конфигураций аннотаций, используя атрибут name как строку.Какова цель атрибута имени аннотации Spring Bean?

@Bean(name = "com.my.injected.Service") 
public InjectedService injectedService() { 
    return injectedService; 
} 

Это имя похоже на Весенний боб XML configuration id and class attributes?

<bean id="..." class="..."> 
    <!-- collaborators and configuration for this bean go here --> 
</bean> 

Почему это не просто

@Bean(clazz = com.my.injected.Service.class) 
public InjectedService injectedService() { 
    return injectedService; 
} 

вместо этого?

Вы в полной мере определяете путь в обоих случаях, и на самом деле использование класса облегчает вашу среду IDE, чтобы рассказать вам, когда вы ее напортачили. Я понимаю, что сначала была создана XML-конфигурация, и, естественно, она всегда искала вещи по строкам, так что это просто перерыв? Есть ли преимущество в использовании строк или основных недостатков для использования .class?

Вопрос был первоначально основан на ложном предположении. Я отредактировал его, чтобы описать, что это за предпосылка, и сделать его менее запутанным для новых людей, которые приходят. Надеюсь, я сделал это так, чтобы данные ответы все еще были применимы; извините, если нет.

+0

Потому что он побеждает цель * называть * что-то. Вы решили предоставить FQN. 'name =" DasBean "' так же хорош. Вы знаете, для чего предназначена эта аннотация? – kolossus

+0

Ха-ха, ясно, что нет. Я думаю, что я должен просто следовать примеру, который злоупотребляет аннотацией. –

ответ

1

Название фасоли не обязательно связано с его классом или даже с любыми интерфейсами, которые он реализует. Это имя и не более того. Когда вы используете конфигурацию аннотации, Spring определяет, какой точный класс или интерфейс предоставляет @Bean, как и весь код java: либо через полное имя в коде, либо через импорт, указанный в файле. В вашем случае у вас, по-видимому, есть оператор import com.my.injected.Service; в верхней части java-файла.

Ваш пример использует полное имя класса в качестве имени компонента. Это твой выбор. Вы можете использовать любой другой идентификатор. Использование полного имени может быть полезно, если ваш код предоставляет объект, который называется точно так же, как и другой сторонний объект @Bean, который должен содержать или использовать ваш код. Однако вы можете так же легко использовать name = "myService".

Название компонента помогает Spring (и прикладному программисту) различать несколько экземпляров одного и того же класса компонентов, поскольку вы можете развернуть один и тот же класс, что и bean, несколько раз. Если появляется только один экземпляр типа bean, вам не нужно указывать имя вручную: весна делает это по умолчанию.

Если у вас несколько бобов, имеющих один и тот же тип или реализующих один и тот же интерфейс, и вы хотите ссылаться на конкретный компонент, используйте аннотацию @Qualifier.

+0

Ах, поэтому единственная причина предоставить полное имя в качестве атрибута 'name' - это если вам нужно переопределить имя по умолчанию, которое я сейчас собираю, это имя метода или объекта, на который вы нажимаете' @ Bean'. Поэтому, если у меня есть 'com.my.injected.Service' и' com.thirdparty.injected.Service' в том же проекте, я мог бы использовать эту полностью квалифицированную схему имен, чтобы устранить эту проблему. –

+0

Да, вы можете. ИМХО такое длинное имя не нужно, но вы можете использовать его, если хотите. Я предпочитаю более короткие имена. Например, у вас есть 2 компонента, которые реализуют 'InjectionServece':' methodInjector' и 'constructionInjector' (я не знаю, имеют ли эти имена смысл для вас, это только, к примеру). В этом случае я бы назвал один из них 'methodInjector', другой' constructorInjector'. – AlexR

1

@Bean аннотация предназначена для обеспечения весеннего боба. Тип компонента, который будет предоставлен, будет тем же самым типом класса/интерфейса, который вы определяете в методе возврата. Таким образом, вместо объявления возврата конкретного класса в методе верните верхний (абстрактный) класс/интерфейс.

Представьте себе этот случай:

public interface MyEntityDao { 
    MyEntity get(String id); 
} 

@Repository 
public class MyEntityDaoDatabaseImpl implements MyEntityDao { 
    @Override 
    public MyEntity get(String id) { 
     /* implementation that goes to database every time */ 
    } 
} 

@Repository 
public class MyEntityDaoCacheImpl implements MyEntityDao { 
    @Override 
    public MyEntity get(String id) { 
     /* implementation that looks the data 
      up in cache, never in database */ 
    } 
} 

@Configuration 
public class MyAppConfiguration { 
    @Bean 
    public MyEntityDaoDatabaseImpl method1() { 
     return new MyEntityDaoDatabaseImpl(); 
    } 
    @Bean 
    public MyEntityDaoCacheImpl method2() { 
     return new MyEntityDaoCacheImpl(); 
    } 
} 

@Service 
public class MyEntityService { 
    @Autowired //what to inject here? 
    MyEntityDao dao; 
} 

В случае, описанном выше, есть две реализации предлагаемого интерфейса. Как инфраструктура может понять, какую реализацию использовать, за исключением имени?

@Service 
public class MyEntityService { 
    @Autowired 
    @Qualifier("properBeanNameToInject") 
    MyEntityDao dao; 
} 
+0

Действительно ли это дает вам право контролировать интерфейс и тип реализации? Страница, которую вы связываете, говорит: @Bean (name = {"b1", "b2"}) // bean доступен как 'b1' и 'b2', но не 'myBean'', что сильно означает, что имя просто предоставляет синтаксический сахара, однако вы хотите ссылаться на инъецируемый объект, как в * других * классах. –

+0

@PatrickM добавил случай, когда имя становится более актуальным, чем верхний класс/интерфейс. –

Смежные вопросы