Spring Beans¶
Одно из ключевых понятий в спринге — это Bean. По сути, это просто объект какого-то класса. Эти объекты создаются с помощью метаданных конфигурации, которые предоставляются контейнеру.
@Bean
public EventLogger consoleLogger() {
return new ConsoleEventLogger();
}
Ссылки:
A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
BeanDefinition¶
В самом контейнере определения bean-компонентов представлены в виде объектов BeanDefinition, которые содержат некоторые метаданные. Эти метаданные преобразуются в набор свойств, которые составляют каждый BeanDefinition:
- Class
Имя класса с указанием пакета: обычно это фактический класс реализации определяемого компонента.
- Name
Каждый Bean имеет один или несколько идентификаторов. These identifiers must be unique within the container that hosts the bean.
A bean usually has only one identifier. However, if it requires more than one, the extra ones can be considered aliases.
Ссылки:
When you create a bean definition, you create a recipe for creating actual instances of the class defined by that bean definition.
- Scope
Определяет отношение между BeanDefinition и конкретными инстансами Bean-ов (например при указании аргументов конструктора или пропертей (см. следующий пункт)).
The Spring Framework supports six scopes, four of which are available only if you use a web-aware ApplicationContext:
- singleton
(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
- prototype
Scopes a single bean definition to any number of object instances.
- request
Scopes a single bean definition to the lifecycle of a single HTTP request.
- session
Scopes a single bean definition to the lifecycle of an HTTP Session.
- application
Scopes a single bean definition to the lifecycle of a ServletContext.
- websocket
Scopes a single bean definition to the lifecycle of a WebSocket.
Ссылки:
- Constructor arguments & Properties
Ссылки на другие bean-компоненты, коллекции, примитивные значения, которые необходимы для работы. These references are also called collaborators or dependencies.
- Autowiring mode
The Spring container can autowire relationships between collaborating beans.
Можно указать autowiring для bean-компонента и, таким образом, можно выбирать, какой именно bean использовать. Описываются следующие autowiring modes:
- no
(Default) No autowiring
- byName
Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired.
- byType
Lets a property be autowired if exactly one bean of the property type exists in the container.
- constructor
Аналогичен byType, но применяется к аргументам конструктора.
public class Application {
private ApplicationUser applicationUser;
public void setApplicationUser(ApplicationUser applicationUser) {
this.applicationUser = applicationUser;
}
}
<!-- byName example -->
<bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>
<bean id="applicationUser" class="com.websystique.spring.domain.ApplicationUser" >
<property name="name" value="superUser"/>
</bean>
- Lazy initialization mode
By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.
Note
When a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized.
- Lifecycle Callbacks
The container calls
afterPropertiesSet()(Initialization method) for the former anddestroy()(Destruction method) for the latter to let the bean perform certain actions upon initialization and destruction of your beans.Tip
The Lifecycle interface defines the essential methods for any object that has its own lifecycle requirements (such as starting and stopping some background process)
Ссылки:
Annotation-based Bean configuration¶
Аннотации поддерживаются характерными ним BeanPostProcessor. CommonAnnotationBeanPostProcessor позволяет использовать конфигурацию с помощью аннотаций, независимо от выбранного BeanDefinitionReader (например через xml)
@BeanПомечает метод в конфигурации или в компоненте (~), как определение бина. Метод впредь будет возвращать конкретное запроксированное представление бина в контексте.
Для данной аннотации присутствуют следующие поля:
- name
Указывает, какое имя будет иметь бин.
- autowire
Указывает, какой Autowiring mode будет у данного бина (см BeanDefinition).
- initMethod
Указывает, какой метод будет обрабатывать событие инициализации этого бина в контексте (см
@PostConstruct).- destroyMethod
Указывает, какой метод будет обрабатывать событие “уничтожения” этого объекта в контексте (см
@PreDestroy).
@ComponentАннотированный класс описывает внутренние свойства BeanDefinition. Имя бина может быть задано параметром в
@Component("name").Сама же декларация бина происходит с помощью аннотации
@Beanили с помощью@ComponentScan.Данная аннотация является базовой для многих других аннотаций в Spring:
@Service(Сервис-слой приложения) Аннотация, объявляющая, что этот класс представляет собой сервис – компонент сервис-слоя.
Сервис является подтипом класса
@Component. Использование данной аннотации позволит искать бины-сервисы автоматически.@Controller(Слой представления) Аннотация для маркировки java класса, как класса контроллера. Данный класс представляет собой компонент, похожий на обычный сервлет (HttpServlet) (работающий с объектами HttpServletRequest и HttpServletResponse), но с расширенными возможностями от Spring Framework.
@Repository(Доменный слой) Аннотация показывает, что класс функционирует как репозиторий и требует наличия прозрачной трансляции исключений. Преимуществом трансляции исключений является то, что слой сервиса будет иметь дело с общей иерархией исключений от Spring (DataAccessException) вне зависимости от используемых технологий доступа к данным в слое данных.
@RestControllerАннотация аккумулирует поведение двух аннотаций
@Controllerи@ResponseBody(показывает что данный метод может возвращать кастомный объект в виде xml, json…).
@PostConstructПомечает метод в компоненте, что он является
post-construct, и вызовется в соответствии с Bean Lifecycle: (afterPropertiesSet()).@PreDestroyПомечает метод в компоненте, что он является
pre-destroy, и вызовется в соответствии с Bean Lifecycle: (destroy()).@DependsOnBeans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean.
Указывается как с
@Bean, так и с@Component.@ScopeСпецифицирует Scope бина.
Указывается как с
@Bean, так и с@Component.@AutowiredАннотированное поле автоматически связывается (позднее связывание при инициализации бина) с конкретным бином в контейнере (по имени/по типу).
Так же можно аннотировать сетер или конструктор - тогда связываться будут параметры сетера или конструктора, при их вызове при инициализации бина.
@PrimaryIndicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency.
Указывается как с
@Bean, так и с@Component.@QualifierСпецифицирует имя бина для связывания. Может быть также указан с конкретными аргументами конструктора или сеттера.
Дефолтный
Qualifier(т.е.AutowiredбезQualifier) - это имя поля.
Note
Инжекшн в спринге вначале отбирает по типам все подходящие бины, далее проверяет по
Qualifierи под конецPrimary.Note
Инжекшн нужно указывать для интерфесов, а не для классов, так как создаются динамические прокси (Proxy) (до Spring 5, после используется только cglib, создающий прокси как объект-наследник) для искомых классов, а сохраняют они при этом интерфейсы а не классы (динамические прокси), по которым будут искаться бины.
@LazyПомечает бин, что он инициализируется, только при первом обращении (Lazy initialization mode).
Аннотируется с
@Beanили с@Component, как и на конфигурации, при этом если помечен компонент - это значит, что сам компонент является Lazy, в противоположность конфигурации - все бины в ней становятся Lazy (см. Annotation-based Configuration).Tip
Со Spring 4.3 можно поставить с анотацией
@Autowired, для пометки того, что инжекшн будет ленивым, т.е. например, это позволит создавать в синглтонах ленивые (по первому вызову) зависимости.@ValueВычисляет указанное spring-expression и присваивает в аннотированное поле / параметр (функции / конструктора)
@ProfileАннотация для создания профилей конфигурации проекта. Может применяться как к бинам так и к конфигурационным классам.
@AspectПомечает класс, использующий aspectj.
@Component
@DependsOn(" ... ")
public class ComponentExample extends SuperComponentExample {
@Autowired
ComponentExample (
@Value("string example") String param,
@Qualifier("dependentBean") MyBean bean
) {
super(fileName);
...
}
@Bean
@Lazy
@Primary
public MyBean bean1() {
return new MyBean();
}
@Bean
@Scope("singleton")
public MyBean bean2() {
return new MyBean();
}
@Bean
@Scope("prototype")
public MyBean bean3() {
assert(bean2() == bean2()) // ибо singleton
return new MyBean();
}
@PreDestroy
public void destroy() {
...
}
}