- util-схема и константы
Было:
С использованием util:constant<bean id="..." class="..."> <property name="isolation"> <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> </property> </bean>
<bean id="..." class="..."> <property name="isolation"> <util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/> </property> </bean>
Для этого нужен spring 2.x и включить util-схему<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
- The p-namespace
вместо кода типа
можно использовать короткую запись установки свойств через т.н. p-namespace:<bean name="classic" class="com.example.ExampleBean"> <property name="email" value="foo@bar.com"/> </bean>
Для этого нужен spring 2.5 и включить p-namespace<bean name="p-namespace" class="com.example.ExampleBean" p:email="foo@bar.com"/>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- использование внешних значений свойств PropertyPlaceholderConfigurer
свойства загружаются из jdbc.properties, который находится в classpath, если же необходимо загрузить свойства из properties-файла, не из classpath, то достаточно указать его путь (относительный или абсолютный):<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
Замечание: можно определить порядок разрешения свойств используя systemPropertiesModeName у PropertyPlaceholderConfigurer:<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>./conf/jdbc.properties</value> </property> </bean>
- SYSTEM_PROPERTIES_MODE_NEVER никогда не проверять системные свойства
- SYSTEM_PROPERTIES_MODE_FALLBACK проверять системные свойства, если не найдено в указанных locations (поведение по-умолчанию)
- SYSTEM_PROPERTIES_MODE_OVERRIDE использовать значения системных свойств в первую очередь и только после искать в locations
Начиная с spring 2.5 существует более краткая запись:
требуется наличие context схемы :<context:property-placeholder location="classpath:jdbc.properties"/>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
Замечание: Вообще, для загрузки spring контекста следует использовать ApplicationContext, а не BeanFactory:
Почему стоит использовать ApplicationContext, а не BeanFactory ?final ApplicationContext context = new FileSystemXmlApplicationContext(fileName);
Если кратко: следует использовать ApplicationContext пока нет действительно весомой причины не использовать его.
Если всё же возникает вопрос «а почему бы и нет ?» стоит читать более подробно и развёрнуто о использовании BeanFactory и ApplicationContext.
Замечание 2: подстановка значений свойств с использованием PropertyPlaceholderConfigurer относится к BeanPostProcessor, и в случае использования BeanFactory подстановка значений свойств не будет произведена. - Spring: Remoting
RMI: Если необходимо выставить pojo объект, например foo.bar.impl.ServiceImpl, по RMI
необходимо, чтобы объект описывал некоторый интерфейс (java интерфейс), в данном случае foo.bar.Service, и выставить его через RmiServiceExporter:<bean id="service" class="foo.bar.impl.ServiceImpl"> <!-- установить все необходимые свойства объекта --> </bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <!-- имя сервиса в реестре RMI, может отличаться от имени bean'а --> <property name="serviceName" value="Service"/> <property name="service" ref="service"/> <property name="serviceInterface" value="foo.bar.Service"/> <!-- порт по-умолчанию: 1099 --> <property name="registryPort" value="1199"/> </bean>
если необходимо выставить несколько интерфейсов, то лучше определить RMI-реестр отдельно:
клиентская часть<bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean" p:port="${rmi.port}" /> <bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <property name="serviceName" value="Service"/> <property name="service" ref="service"/> <property name="serviceInterface" value="foo.bar.Service"/> <property name="registry" ref="rmiRegistry"/> </bean>
вот и всё, что нужно для обращения к объекту выставленному по RMI, все вызовы прозрачно происходят через spring proxy.<bean id="service" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" p:serviceUrl="rmi://HOST:1199/Service" p:serviceInterface="foo.bar.Service" p:refreshStubOnConnectFailure="true" p:lookupStubOnStartup="false" />
Spring's HTTP invoker
server side:
client side:<util:map id="serviceEndpoints"> <entry key="/Service"> <bean class="org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter" p:serviceInterface="foo.bar.service" p:service-ref="service" /> </entry> </util:map> <bean id="httpServer" class="org.springframework.remoting.support.SimpleHttpServerFactoryBean" p:port="${server.port}" p:contexts-ref="serviceEndpoints"/>
<bean id="service" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean" p:serviceUrl="${http.server.url}/Service" p:serviceInterface="foo.bar.Service"> <qualifier value="remoted" /> </bean>
- Spring & JUnit
Используя JUnit 4.4 и Sprint 2.x можно перенести загрузку контекста spring в annotations: хорошая статья о том как тестировать Spring-приложение с помощью JUnit
Замечание: Требуется JUnit 4.4, spring-test.jar, тесты должны быть в стиле JUnit4 (с использованием annotations)
дополнено:
По-умолчанию @Autowire работает по autowire-by-type (связывание по типу), всё хорошо, когда с spring контексте только один bean данного типа, когда появляется ещё один bean такого же типа - появляется неоднозначность выбора необходимого bean'а - для этого используется @Qualifier с указанием имени bean'а@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:test-spring-config.xml"}) public class SomeTest { @Autowired private Foo foo; @Autowired @Qualifier(value="bar") private Bar bar; @Test public void testingSmth(){ // ... } }
когда же появляются типизированные коллекции или типизированные объекты Autowire буквально сносит мосх в виде неразрешённых зависимостей...
Поэтому, рекомендуется использовать @Resource вместо @Autowired.
@Resource входит в JSR 250 и входит в состав java 6, для java 5 придётся подключать jsr250-api-1.0.jar.
Замечание: В @Resource также можно указывать и имя ресурса, тем самым нет необходимости использовать @Qualifier@Resource(name="smthBeanName")
Источник: @Autowire does not work as expected for Collections based Repository implementation - Вызов статического метода
<bean id="ui" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" p:staticMethod="javax.swing.UIManager.setLookAndFeel"> <property name="arguments"> <list> <value>com.jgoodies.plaf.plastic.PlasticXPLookAndFeel</value> </list> </property> </bean>
Unveiling Floating-Point Modulus Surprises in Java
8 часов назад
4 комментария:
Очень полезно, спасибо.
К слову о <context:property-placeholder/>, стоит упомянуть необходимость импорта соотвествующей схемы:
xmlns:context = "http://www.springframework.org/schema/context"
Володя, замечание к твоему замечанию =)
"подстановка значений свойств с использованием PropertyPlaceholderConfigurer относится к BeanPostProcessor, и в случае использования BeanFactory подстановка значений свойств не будет произведена."
Стоит добавить, что подстановка значений не будет произведена по умолчанию. При этом никто не мешает сделать пост-конфигурацию фабрики приямо из Java, хотя это и менее удобно:
final Resource resource = new ClassPathResource("jdbc.properties");
final PropertyResourceConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setLocation(resource);
configurer.postProcessBeanFactory(factory);
@Andrew ``Bass'' Shcheglov:
спасибо, уместные замечания.
@Resource вместо @Autowired не получится использовать под Jboss ~5.1 - он считает их JEB-аннотациями (требует указать mapping-name, а если дать - не находит его в JNDI)
Отправить комментарий