Ответ 1
@Component
и @Configuration
действительно очень разные типы аннотаций.
@Component
и аналогичные аннотации (@Service
, @Repository
и т.д.) и его JSR-330 @Named
allow вы объявляете beans, которые должны быть взяты автосканированием с помощью <context:component-scan/>
или @ComponentScan
, они регистрируют определение bean для классов, поэтому они примерно эквивалентны объявлению указанного beans с помощью <bean ... />
тег в XML. Эти типы bean будут придерживаться стандартных политик создания прокси.
@Configuration
аннотация была разработана как замена файла конфигурации XML. Чтобы создать @Configuration
аннотированный beans, Spring всегда будет использовать CGLIB
для подкласса аннотированного класса @Configuration
, переопределяя его аннотированный метод @Bean
, чтобы заменить его методом поиска bean, чтобы сделать singleton beans создается только один раз. (Spring не использует CGLIB
для перехвата внутренних вызовов метода из нормального Spring beans, вместо этого он создает отдельный экземпляр прокси (так же, как прокси-сервер JDK). Это позволяет использовать прокси, чтобы избежать мощности несоответствие - например, прокси-синглтон может получить текущий сеанс bean, что невозможно с наследованием класса.). Несмотря на это, аннотированные классы @Configuration
все еще могут использовать аннотированные (@Autowired
, @Inject
и т.д.) Поля и свойства для запроса beans (и даже других @Configuration
аннотированных beans тоже) из контейнера.
Пример из раздела 4.12.5 документации
@Configuration
public class AppConfig {
@Bean
public ClientService clientService1() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
в приведенном выше примере будет создан только один экземпляр ClientDao
.
@Autowired
- аннотация Spring, а @Inject
- аннотация JSR-330.
@Inject
эквивалентен @Autowired
или @Autowired(required=true)
, но вы не можете получить поведение @Autowired(required=false)
с аннотацией JSR-330 @Inject
. В этой аннотации всегда используется автоподключение по типу.
Spring значительно упрощает аннотацию JSR-250 @Resource
. @Resource
изначально был предназначен для размещения ресурсов JNDI в Java EE, но Spring расширяет его применимость, позволяя подключаться к любому bean в контейнере (ресурсы JNDI доступны как beans с помощью SimpleJndiBeanFactory).
Имя соответствующего bean может быть указано как name
атрибут @Resource
аннотации, если имя не указано, тогда будет использовано имя аннотированного поля или свойства. Еще одна странная особенность заключается в том, что если не было найдено bean с именем свойства Spring, произойдет откат к проводке по типу.
Пример
Представьте, что в контейнере есть AlphaClass
bean с именем beanAlpha и beanBeta BetaClass
bean.
@Resource
BetaClass something; // Wires to beanBeta - by-type
@Resource
BetaClass beanAlpha; // Will throw exception, because "beanAlpha" is not BetaClass -> it a bad idea to use @Resource as a replacement of @Autowired
@Resource
Object beanAlpha; //Wires to beanAlpha - by-name
Так что хорошая практика всегда указывать имя ресурса явно при использовании аннотации @Resource
.
Documentation
обновить фиксированные ссылки JSR, как указал shevchik. Отдельные аннотации DI предоставляются JSR-330, который был разработан инженерами Google (Guice Framework) и SpringSource (Spring Framework). @Resource
основан на JNDI и предоставляется JSR-250.