I hava a spring 4 mvc controller. I am using annotations to handle multiple requests in the same controller. - e.g.
#RequestMapping("/add_dob")
public String addDateOfBirth(.......) {
........
validateDOB(form, result)
........
}
#RequestMapping("/add_address")
public String addAddress(.......) {
........
}
The thing is that I have a session command object (PERSON) and there is a possibility of the command object becoming inconsistent. I tried using
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="synchronizeOnSession" value="true" />
</bean>
in the servlet-name.xml spring file but this is causing all requests on the application to be synchronized (I tested by putting Thread.sleep inside the request on which I intend to synchronize and then tried to access the home page). Is there any way by which I can just synchronize on the session command object or on a scope smaller than the entire session?
Thanks
You could use a specific session-scoped bean, e.g. Person:
<bean class="com.xyz.Person" scope="session">
<aop:scoped-proxy/>
</bean>
Or with annotations:
#Bean #Scope("session") #ScopedProxy class Person {...}
You can then #Autowire this bean to your web service class. Spring guarantees that any time you reference it you will receive the object from the current session. See here for more details.
Related
I'm searching for a possibility to inject a property which is defined in a spring context (provided by a propertiesFactoryBean) into a wicket component. I know the way to inject beans into components by using the #SpringBean-Annotation, but whats the corresponding way for properties?
The way my property is defined:
<bean id="myPropertiesFactory" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="mySpringProperty">mySpringProperty</prop>
</property>
</bean>
Things I've tried. The way it works usually with self defined beans:
#Inject
#Value("${mySpringProperty}")
Using the name of the propertiesFactory to access the property value
#Inject
#Value("$myPropertiesFactory.properties.mySpringProperty")
Using the Value Annotation
#Value("#myPropertiesFactory['mySpringProperty']")
Using SpringBean
#SpringBean(name="myPropertiesFactory.mySpringProperty")
None of these solutions works. So to get mySpringProperty injected i use the workaround to create a bean of the type String which get's injected properly by wicket when i annotate the corresponding member of my component with SpringBean but i think there must be a better solution.
<bean id="mySpringPropertyBean" class="java.lang.String">
<constructor-arg type="java.lang.String" value="https://foobar.com" />
</bean>
Annotate
#SpringBean
private String mySpringPropertyBean;
#SpringBean only supports injection of spring beans. I suppose someone could implement a #SpringValue annotation that does what you want, but as far as I know noone ever did.
What I usually do is:
My wicket application class is a spring bean.
It has properties with #Value annotations - as the object is a spring bean, these are evaluated and set properly
I access the actual values by calling MyApplication.get().getXXX() or ((MyApplication)getApplication()).getXXX()
If the app grows and the number of attributes approach a limit, I refactor them into separate Settings or Config classes - each one a spring bean of it's own, accessible from the application class.
In your Wicket class use instead of #Value("${mySpringProperty}"):
#SpringBean
private PropertiesConfiguration propertiesConfiguration;
Create a new PropertiesConfiguration class:
#Component
public class PropertiesConfiguration {
#Value("${mySpringProperty}")
private String mySpringProperty;
//getters & setters
}
Use in your wicket class:
System.out.println("mySpringProperty=" + propertiesConfiguration.getMySpringProperty());
I wonder how can I properly inject a prototype bean to a singleton one in a web app. Consider this example:
<bean id="order" class="com.foo.Order" scope="prototype"/>
<bean id="orderService" class="com.foo.OrderService">
<property name="userPreferences" ref="userPreferences"/>
</bean>
I thought of using getBean() but isn't that a way to make my code dependent to spring itself?
I need a short java code example to demonstrate how to inject an order bean in my OrderService singleton.
Thanks
You can use jsr-330 Providers, just put:
#Autowired
Provider<Order> orderProvider;
in your singleton bean, and then use the provider:
public Whatever yourMethod() {
Order order = orderProvider.get();
}
I'm writing an integration test where an application context xml is initialized during startup. There are several test methods in the test class which make use of a specific bean 'X'(already defined in the xml). My actual requirement is to mock bean X only for one of the test methods.
Inside a test method: I tried creating a separate application context using ClassPathXMLApplicationContext with only the mock bean 'M'.
Now I have two Application Contexts (AC):
1. One created during test case startup (which contains the actual bean X) and
2. One created using ClassPathXMLApplicationContext within the test method (which has the mock bean M).
I want to replaced the actual bean definition 'X' within AC:1, using the mock bean definition 'M' from AC:2.
Can somebody throw some light on this please?
You can :
use the Profile annotation if you have spring 3.1.
use the Primary annotation
use qualifiers
wire the bean yourself in the spring context
and i'm sure there are even more options.
There is not a clear way to replace a a bean in a refreshed ApplicationContext unless you close it and refresh it again.
To emulate it, the common approach is to use a Proxy of the bean that you want to replace and change the target at runtime.
You can do it easily using the framework aop support classes:
<bean id="realBean" class="RealClass" />
<bean id="mockBean" class="MockClass" />
<bean id="targetSource" class="org.springframework.aop.target.HotSwappableTargetSource">
<constructor-arg ref="realBean" />
</bean>
<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="targetSource" />
</bean>
#Test
public void testWithMockBean() {
Object real = targetSource.swap(mock);
....
// do your test work
...
targetSource.swap(real);
}
Create a testApplicationContext with
<beans>
<import resource="classpath*:appContext.xml" />
<bean id="mockbeanOfX" class=....../>
</beans>
and then load this test application context in your testcase. Now you can get the mock bean from the application context and pass it whereever needed.
I am making a new Java webapp with Spring MVC 3.0 and want to use as much standard Java EE 6 stuff as I can. (I'm on Glassfish 3.1.1.) The real driver is wanting to use an MVC web framework rather than JSF.
So I'm looking for the best way to inject EJBs into my Spring controllers. I had some success but I'm not happy with how it looks and I was hoping to find a better way.
This worked, by finding the EJB via JNDI:
// EJB
#Stateless
public class Service {
#PersistenceContext(name="MAIN")
private EntityManager em;
public void doSomething() { .... }
}
// Spring
#Controller
public class HomeController {
#EJB(mappedName="java:global/springtest/Service")
private Service service;
// controller methods use service
}
But I'm unhappy with needing the "mappedName" on the #EJB annotation in the controller.
Is there a better way to do this?
The good news, though, is that I can use the same #Inject annotation in EJBs and Spring beans and the only difference is which framework is creating the object and doing the injection.
If you use
mappedName="java:module/Service"
instead of
mappedName="java:global/springtest/Service"
you do not have to worry about the appname.
This makes the code more portable. I guess that will solve some of your problems
For Spring, you could wrap the JNDI lookup into JndiObjectFactoryBean:
<bean id="serviceBean" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:global/springtest/Service" />
<property name="resourceRef" value="true" />
</bean>
Then you'll probably (correct me if I'm wrong) be able to use it with #Inject without the #Named("serviceBean") annotation:
#Inject
private Service service;
<bean id="userFacade" class="com.test.facade.UserFacadeImpl">
<property name="userDao" ref="userDao"/>
<property name="currentUser" ref="user"/>
</bean>
<bean id="user" class="com.test.beans.User" scope="session">
<aop:scoped-proxy/>
</bean>
UserDao and user are passed to it - user being a scope and facade a singleton. So any request to userfacade is going to return a same object but user will be different for each session - the concept session inside a singleton confuses me. Can someone explain?
The "scoped proxy" is a transparent wrapper around your User bean. When a method on that proxy is invoked, it will look up the current HttpSession using Spring's thread-local mechanism (called the RequestContextHolder), and then fetch the User object from inside the session's attributes. If none exists in that session, a new one is created and stored in the session. The "real" method on that User is then invoked.
The big caveat with scoped proxies is that the proxy's methods can only be invoked if the scope is "active", e.g. if the currently executing thread is a servlet request.
The instance of User injected into UserFacadeImpl is a proxy which delegates method calls to the actual session-scoped instances of User.
See also:
Proxy pattern