Pro Spring 4
Жизненный цикл Spring Bean
InitializingBean
Вызывается метод afterPropertiesSet(), который служит той же цели, что и метод init()
@PostConstruct
Начиная с версии Spring 2.5, поддерживаются также и аннотации JSR-250 для указания метода, который платформа Spring должна вызвать, если соответствующая аннотация, связанная с жизненным циклом бина, существует в классе. Это тот же init-method, только имя метода может быть любым. Для работы необходимо добавить дескриптор context:annotation-config.
DisposableBean
Вызывается метод destroy(), который служит той же цели, что и метод указываемый в атрибуте destroy-metod.
@PreDestroy
Применение аннотации жизненного цикла @PreDestroy, определенной в стандарте JSR-250, которая является противоположностью @PostConstruct. Для работы необходимо добавить дескриптор context:annotation-config.
Конфигурация XML
beans
beans default-lazy-init
Атрибут инструктирует Spring о том, что экземпляры бинов, определенных в конфигурационном файле, должны создаваться только при их запросе приложением.
<beans ... default-lazy-init = "true"> <bean ... /> ... </beans>
context:component-scan
Дескриптор <context:component-scan> сообщает Spring о необходимости сканирования кода на предмет внедряемых бинов, аннотированных с помощью @Component, @Controller, @Repository и @Service, а также поддерживающих аннотации @Autowired и @Inject в указанном пакете (и всех eгo внутренних па кетах). В дескрипторе <context:component-scan> можно определить множество пакетов, используя в качестве разделителя запятую, точку запятой или пробел. Кроме того, для более детализированного управления этот дескриптор поддерживает включение и исключение сканирования компонентов. Также можно указать пакет для сканирования через установку атрибута base-package. Еще можно указать исключения через context:exclude-filter.
bean
bean/property
name - Имя свойства бина value - значение (простой тип)
До версии 2.5:
ref - ссылка на другой бин по id
Применение атрибута local означает, что дескриптор ref всегда просматривает только идентификатор бина и никогда не принимает во внимание его псевдонимы:
<ref local="test"/>
Более того, определение бина должно существовать в том же самом ХМL-файле конфигурации.
Пример ссылки на бин (ссылка текущий, дочерний, родительский контекст)
<ref bean="newBean"/>
Пример ссылки на бин родительского контекста
<ref parent="newBean"/>
С версии 2.5: конфигурировать можно не через property, а в самом bean так:
p:<тут имя свойства>-ref="id другого бина"
или так
p:<тут имя свойства>="простое значение"
Через SpEL:
p:name = "#{injectSimpleConfig.name}"
bean/property/map
Пример:
<property name="map"> <map> <entry key="v1"> <value>Hello World!</value> </entry> <entry key="refToBean"> <ref local="localBeanId"/> </entry> </map> </property>
bean/property/set
<property name="set"> <set> <value>Hello World 1 </value> <ref local="oracle" /> </set> </property>
bean/property/list
<property name="list"> <list> <value>Hello World!</value> <ref local="localBeanId"/> </list> </property>
bean/property/props
Дескриптор <props> позволяет передавать в качестве значений только String, потому что класс Properties разрешает только значения свойств типа String. Пример:
<property name="props"> <props> <prop key="firstName">Sasha</prop> <prop key="secondName">V.</prop> </props> </property>
bean/constructor-arg
До версии 3.1: constructor-arg определяет Constructor Injection. Всегда лучше применять атрибут index, чтобы избежать путаницы между параметрами.
С версии 3.1: можно применять в bean выражение вида c:<свойство>=<значение> или _<digit> - как указание индекса аргумента конструктора
<bean id="message" class="java.lang.String" с:_O="message"/>
Если есть 2 конструктора с одинаковыми именами параметров, то можно указать тип
<constructor-arg type="int"><value>1</value><constructor-arg>
bean/lookup-method
Пример Method Injection:
<bean id="abstractLookupBean" class="com.a.AЬstractLookupDemoBean"> <lookup-method name="getMyHelper" bean="helper"/> </bean>
bean/replaced-method
<bean id="replacementTarget" class="com.a.ReplacementTarget"> <replaced-method name="formatMessage" replacer="methodReplacer"> <arg-type>String</arg-type> </replaced-method> </bean>
bean name-алиасы
Через name:
<bean id="name1" name="name2 name3,name4;name5" class="java.lang.String"/>
Через alias:
<alias name = "namel" alias = "name6"/>
Извлечь список псевдонимов бина можно с помощью вызова метода ApplicationContext.getAliases(String) с передачей ему любого из имен бина или его идентификатора. Этот метод возвращает в виде массива String список псевдонимов, содержащий все псевдонимы кроме указанного при вызове.
bean scope
По умолчанию Spring устанавливает атрибут scope в singleton (одиночный). Область действия на уровне prototype (прототип) заставляет Spring создавать новый экземпляр бина каждый раз, когда он запрашивается приложением. Пример:
<bean id="nonSingleton" class="java.lang.String" scope="prototype" c:_0="Sasha V."/>
bean depends-on
В следующей конфигурации мы утверждаем, что бин по имени beanA зависит от бина под названием beanB.
<bean id="beanA" class="BeanA" depends-on="beanB"/> <bean id="beanB" class="BeanB"/>
Во время разработки приложений такого подхода лучше избегать; вместо этого определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.
bean autowire
В атрибуте autowire для бина понадобится указать используемый режим автосвязывания. Платформа Spring поддерживает следующие режимы автосвязывания: byName, ЬуТуре, constructor, default и no (автосвязывание отключено; устанавливается по умолчанию).
bean lazy-init
Атрибут lazy-init устанавливается в true, чтобы информировать Spring о необходимости создания экземпляра бина только при первом его запросе, а не во время начальной загрузки.
bean parent
Наследование бинов:
<bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/> <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/>
bean abstract
В случае если определение родительского бина не должно быть доступным для поиска из ApplicationContext, к дескриптору bean, объявляющему родительский бин, можно добавить атрибут abstract="true".
bean init-method
Атрибут init-method, который сообщает платформе Spring, что она должна вызвать метод init(), как только завершит конфигурирование бина.
<bean id="iBean" class="BeanClass" init-method="init"/>
Аналоги: InitializingBean.afterPropertiesSet(), @PostConstruct
bean destroy-method
Чтобы назначить метод для вызова во время уничтожения бина, нужно просто указать имя этого метода в атрибуте destroy-method дескриптора <bean> для бина. Платформа Spring вызывает этот метод непосредственно перед уничтожением одиночного экземпляра бина (она не будет вызывать этот метод для бинов с областью действия на уровне прототипа).
<bean id="dBean" class="BeanClass" destroy-method="destroy"/>
Аналоги: DisposableBean.destroy(), @PreDestroy
util
Пространство имен util, предоставляемое Spring, для объявления бинов, хранящих свойства коллекций.
util:map
<util:map id="map" map-class = "java.util.HashMap"> <entry key = "someValue"> <value>Hello World!</value> </entry> <entry key="someBean"> <ref bean="beanId"/> </entry> </util:map>
util:properties
<util:properties id="props"> <prop key="firstName">Sasha</prop> <prop key = "secondName">V.</prop> </util:properties>
util:set
<util: set id="set"> <value>Hello World!</value> <ref bean = "oracle"/> </util: set>
util:list
<util:list id="list"> <value>Hello World!</value> <ref bean="oracle"/> </util:list>
Кофигурация аннотациями
@Autowired
Если указано на setter, то происходит автоматическое связывание.
Если указано на construcor, то происходит автоматическая передача параметра, пример:
@Autowired public NewConstructor (@Value ( "message") String message) { this.message = message; }
Аннотация @Autowired может быть применена только к одному из методов конструкторов.
@Inject
В спринг аналогична автоматическому связыванию (JSR-299).
@Resource
Пример - @Resource (name = "messageProvider") указывается для поддержки автоматического связывания. (JSR-250)
@Value
Предназначена для определения значения, подлежащего внедрению. Свойства:
@Value("32") private int age;
Через SpEL:
@Value("#{injectSimpleConfig.name}")
Жесткое кодирование значения не является удачной идеей, т.к. его изменение влечет за собой перекомпиляцию программы.
@Service
Пример - @Service("messageRenderer") указывает, что этот бин предоставляет службы, которые могут требоваться другим бинам; в качестве параметра аннотации передается имя бина.
@Component
@Component("injectSimpleConfig") @Service является специализацией @Component, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения.
Классы Spring
StopWatch
org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.
StopWatch stopWatch = new StopWatch(); stopWatch.start("demo"); for (int х = О; х < 100000; х++) { MyHelper helper = bean.getMyHelper(); helper.doSomethingHelpful(); } stopWatch.stop(); System. out. println ( "100000 gets took " + stopWatch. getTotalTimeMillis () + " ms");
AbstractApplicationContext
AbstractApplicationContext.registerShutdownHook
registerShutdownHook - создать перехватчик завершения (shutdown hook) - поток, который выполняется непосредственно перед завершением приложения. Это отличный способ вызвать метод destroy () вашего класса AbstractApplicationContext (который расширяется всеми конкретными реализациями ApplicationContext).
Пример для автономного приложения:
ctx.load("classpath:META-INF/spring/app-context-annotation.xml"); ctx.registerShutdownHook(); ctx.refresh();
Можно определить бин, который автоматом сделает тоже самое
<bean id="shutdownHook" class="ShutdownHookBean"/>
где ShutdownHookBean implements ApplicationContextAware с таким методом setApplicationContext:
if (ctx instanceof GenericApplicationContext) { ((GenericApplicationContext)ctx).registerShutdownHook(); }
AbstractApplicationContext.destroy
Единственный недостаток обратных вызовов уничтожения в Spring связан с тем, что они не запускаются автоматически, т.е. перед закрытием приложения нужно не забыть вызвать AbstractApplicationContext.destroy(). Когда приложение выполняется как сервлет, указанный метод destroy() можно вызвать в методе destroy() сервлета. Однако в автономном приложении все не так просто, особенно при наличии множества точек выхода из приложения. К счастью, решение есть. Java позволяет создать перехватчик завершения (shutdown hook). См. AbstractApplicationContext.registerShutdownHook
BeanNameAware
Интерфейс BeanNameAware, который бин может реализовать, чтобы получить свое имя, имеет единственный метод: setBeanName (String)
ApplicationContextAware
Интерфейс ApplicationContextAware, который бин может реализовать, чтобы получить ссылку на контекст ApplicationContext, который их сконфигурировал. Имеет метод: setApplicationContext(ApplicationContext ctx) throws BeansException
FactoryBean
В интерфейсе FactoryBean объявлены три метода: getObject(), getObjectType() и isSingleton(). Реализуя этот интерфейс и добавив в него управляющее свойство, можно создавать бины с соответствующего типа, которые будут возвращаться через getObject().