Programmatically set property of bean - spring

I am trying to figure out how I can adjust the "period" property of the "destroyWorldTask" bean that is defined like this in my list of beans. Is this possible? What is the proper way to do this?
<bean id="mytimerfactory"
class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="daemon" value="true"/>
<property name="myTimerTasks">
<list>
<bean class="org.springframework.scheduling.timer.ScheduledTimerTask" id="destroyWorldTask">
<property name="delay" value="100"/>
<property name="period" value="10000/>
<property name="runnable">
<bean class="com.scene7.is.util.SafeRunnable">
<constructor-arg ref="destroyWorld"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>

There are two possible answers:
1. If you want the "period" property be set somewhere in the program, you don't need to set in the context configuration. (Which I think not suitable for you, as you are using a spring class, not yours).
2. Extend from org.springframework.scheduling.timer.ScheduledTimerTask and make your edition of the class, something like:
public MyTimeScheduledTimerTast extends ScheduledTimerTask{
//...
}
and set that property in your program. (Now it's in your hand)
Then update your context configuration like this:
<bean id="mytimerfactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="daemon" value="true"/>
<property name="myTimerTasks">
<list>
<bean class="myPackage.MyScheduledTimerTask" id="destroyWorldTask">
<!-- Set those properties that are not set in your program -->
</bean>
</list>
</property>
</bean>

Related

java spring session how to custom cookie key

I using spring session HttpSession, how can I custom cookie key, I tried this solution: Custom cookie name when using Spring Session. but it does not work, the name is SESSION still.
my config like below:
<context:annotation-config/>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
<context:property-placeholder location="classpath:/env/env_test.properties"/>
<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:port="${spring.redis.port}" p:hostName="${spring.redis.host}"/>
<bean id="mapSessionRepository" class="org.springframework.session.MapSessionRepository" />
<bean id="sessionRepositoryFilter"
class="org.springframework.session.web.http.SessionRepositoryFilter">
<constructor-arg ref="sessionRepository"/>
<property name="httpSessionStrategy">
<bean class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<property name="cookieName" value="_session_id" />
</bean>
</property>
</bean>
You just need to add below bean to create custom cookie.
<bean class ="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookieName" value="JSESIONID"></property>
</bean>
JESSIONID - Custom Cookie Name
Please remove below configuration fr`enter code here`om xml file.
<bean id="sessionRepositoryFilter"
class="org.springframework.session.web.http.SessionRepositoryFilter">
<constructor-arg ref="sessionRepository"/>
<property name="httpSessionStrategy">
<bean class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<property name="cookieName" value="_session_id" />
</bean>
</property>
</bean>
You have to create a bean with class
org.springframework.session.web.http.DefaultCookieSerializer
So inside of that bean, you define your custom properties, after you declare that bean as a property of the following:
org.springframework.session.web.http.CookieHttpSessionStrategy
By example:
<bean id="yourCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookieName" value="yourCustomName"/>
<property name="cookiePath" value="yourCustomPath"/>
...
</bean>
<bean id="cookieHttpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<property name="cookieSerializer" ref="yourCookieSerializer"></property>
</bean>

Can we use single JedisConnectionFactory instance with multiple spring redis template?

I have multiple Spring Redis Template with diffrent serializers. Can I use same JedisConnectionFactory instance for both?
Yes, you can use the same JedisConnectionFactory with multiple Spring Redis templates by specifiying the connectionFactory property in the bean definition for your Redis template(s).
Example:
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379"/>
<property name="usePool" value="true"/>
</bean>
<bean id="redisTemplateOne" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">
<bean class="com.example.KeyOne"/>
</property>
<property name="valueSerializer">
<bean class="com.example.ValueOne"/>
</property>
</bean>
<bean id="redisTemplateTwo" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">
<bean class="com.example.KeyTwo"/>
</property>
<property name="valueSerializer">
<bean class="com.example.ValueTwo"/>
</property>
</bean>

How does one make Spring read from a file to string property?

I have a bean that has a string property that I would like to set, but I would like it set from a file without changing the bean code. The bean is something like this.
public class SomeBean {
public void setSomeProperty(String string) { ... }
}
I was looking for something like this in the beans.xml file
<beans>
<bean class="SomeBean">
<property name="someProperty">
<util:string src="classpath:foo.txt" />
</property>
</bean>
</beans>
Try using the PropertyPlaceholderConfigurer to load a value from a properties file:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:foo.properties</value>
</list>
</property>
</bean>
<bean class="SomeBean">
<property name="someProperty" value="${myBean.someProperty}" />
Then, in the foo.properties file, you set the property to whatever value you want:
myBean.someProperty = value
Hope this helps
I found a way using the Guava classes though it looks really bad.
(The value attribute is all in one line)
<property name="someProperty"
value="#{ T(com.google.common.io.Resources).toString(
T(com.google.common.io.Resources).getResource('foo.txt'),
T(java.nio.charset.Charset).forName('UTF-8')) }"/>
Hopefully someone can find a better answer.

Spring: How to inject a property with a non-setter method?

Is it possible to inject a property bean through a method with a signature doesn't start with set?
Specifically, I'm trying to use Spring to configure an embedded Jetty instance and I need to be able to inject a servlet bean via an addServlet() method.
I am looking at Jetty/Tutorial/Embedding Jetty documentation. I guess you mean calling ServletContextHandler.addServlet(). You have few choices:
#Configuration (since 3.0)
My favourite approach. You can configure everything using Java!
#Configuration
public class Jetty {
#Bean(initMethod = "start")
public Server server() {
Server server = new Server(8080);
server.setHandler(context());
return server;
}
#Bean
public ServletContextHandler context() {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(servlet(), "/*");
return context;
}
#Bean
public ServletHolder servletHolder() {
return new ServletHolder(helloServlet());
}
#Bean
public HelloServlet helloServlet() {
return new HelloServlet();
}
}
Inheritance/decorating
You can inherit from or wrap original ServletContextHandler class to follow Java bean naming conventions. Of course it requires an extra class, but makes Jetty class Spring-friendly. You can even publish such wrapper or maybe someone already did that?
MethodInvokingFactoryBean
I don't like this approach as it seems too low level. Basically you create a bean that calls arbitrary method with arbitrary arguments:
<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="servletContextHandler"/>
<property name="targetMethod" value="addServlet"/>
<property name="arguments">
<list>
<ref bean="yourServlet"/>
</list>
</property>
</bean>
just the spring file adapted to Jetty 7. It's possible to add yours contextHandlers...
<bean id="contexts"
class="org.eclipse.jetty.server.handler.ContextHandlerCollection" />
<context:property-placeholder location="src/main/resources/ws.properties" />
<!-- Manually start server after setting parent context. (init-method="start") -->
<bean id="jettyServer" class="org.eclipse.jetty.server.Server"
destroy-method="stop">
<property name="threadPool">
<bean id="ThreadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<property name="minThreads" value="10" />
<property name="maxThreads" value="50" />
</bean>
</property>
<property name="connectors">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<property name="port" value="8181" />
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="contexts" />
<bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" />
<bean class="org.eclipse.jetty.servlet.ServletContextHandler"
p:contextPath="/${ws.context.path}">
<property name="sessionHandler">
<bean class="org.eclipse.jetty.server.session.SessionHandler" />
</property>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder"
p:name="spring-ws">
<property name="servlet">
<bean
class="org.springframework.ws.transport.http.MessageDispatcherServlet" />
</property>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:/spring-ws-context.xml" />
</map>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping"
p:servletName="spring-ws" p:pathSpec="/*" />
</list>
</property>
</bean>
</property>
</bean>
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler" />
</list>
</property>
</bean>
</property>
</bean>

How to add more hbm to existing mappingResources or existing hbm list in Spring

I have a parent-app, which includes sub-apps.
My Parent app has its own included list of hbms
<bean name="mappingResources"
class="my.xxx.MyListFactoryBean">
<property name="sourceList">
<list>
<value>aaa/bbb/aa.hbm.xml</value>
<value>aaa/bbb/bb.hbm.xml</value>
<value>aaa/bbb/cc.hbm.xml</value>
</list>
</property>
</bean>
My sub-apps want to add its own list of dependent hbms to the parent-app's.
The way it should work is, if it includes this sub-app then it would include the new hbms as well and the child-app would initiate the include.
new hbms to be included could look like
xx/dd.hbm.xml
xx/ee.hbm.xml
How can we do it?
Your Solution could be:
Split up the 'mappingResources' to
<bean name="mappingResources" class="my.xxx.MyListFactoryBean">
<property name="sourceList" ref="hbmSourceList" />
</bean>
<bean id="hbmSourceList" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>aaa/bbb/aa.hbm.xml</value>
<value>aaa/bbb/bb.hbm.xml</value>
<value>aaa/bbb/cc.hbm.xml</value>
</list>
</constructor-arg>
</bean>
In the child-app
refer to the bean "hbmSourceList" and invoke an "addAll" on it with an another list via the "MethodInvokingFactoryBean"
<bean id="hbmSourceListExtender" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref bean="hbmSourceList"/></property>
<property name="targetMethod"><value>addAll</value></property>
<property name="arguments">
<ref local="childAppHbmSourceList"/>
</property>
</bean>
<bean id="childAppHbmSourceList" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>xx/dd.hbm.xml</value>
<value>xx/ee.hbm.xml</value>
</list>
</constructor-arg>
</bean>

Resources