Spring AOP and aspect thread safety for an autowired HTTPServletRequest bean - spring

I am using Spring 3 AOP, and I have an aspect that requires access to the HttpServletRequest. It looks something like this:
#Aspect
public class MyAspect {
#Autowired
private HttpServletRequest httpServletRequest;
public void init() {
// Do something once...
}
#Before("my pointcut here...")
private void myMethod() {
// I need the httpServletRequest...
}
#After("my pointcut here...")
private void myOtherMethod() {
// I need the httpServletRequest...
}
}
And is configured like this:
<bean id="myAspect" class="com.some.package.MyAspect" init-method="init" />
Is the init method only called once per IoC container, even though this is an aspect, and is the httpServletRequest thread safe? If it is not, what is the best way to get at it during execution of the advice and have it be thread safe? If at all possible I prefer not to use a thread local.

Is the init method only called once per IoC container
It is called once per every bean instance. If bean has a singleton scope (which is the default case for aspects as well), it will only be called once. However you won't have access to the httpServletRequest inside init() method - there is no request yet!
is the httpServletRequest thread safe
It is not but don't worry. This is actually much more complex than it looks like. You are injecting HTTP servlet request (and obviously there can be several requests available at the same time) into a singleton object. Which one is injected? None (all?) of them! Spring creates some sophisticated proxy (called scoped proxy) and every time you access methods of injected httpServletRequest it delegates them to current (to thread) request. This way you can safely run your aspects in several threads - each will operate on a different physical request.
This whole behaviour is described in great details in 4.5.4.5 Scoped beans as dependencies:
[...] If you want to inject (for example) an HTTP request scoped bean into another bean, you must inject an AOP proxy in place of the scoped bean. That is, you need to inject a proxy object that exposes the same public interface as the scoped object but that can also retrieve the real, target object from the relevant scope (for example, an HTTP request) and delegate method calls onto the real object.
About ThreadLocal:
I prefer not to use a thread local.
Fortunately - Spring is using one for you. If you understand how ThreadLocal works - Spring puts current request into a thread local and delegates to thread-local instance when you access httpServletRequest proxy.

Related

Spring lookup-method and scoped proxy usage

I'm a bit confused about using method injection (lookup-method) and aop scoped-proxy (Since both used for different scoped beans injection) so
1) When to use method injection and when to use aop-scoped proxy ?
2) What is the reason why a aop-scoped proxy will not be used for a prototype bean ?
Both lookup method injection and scoped proxy are means to inject shorter lived beans into longer lived beans. However, they serve different use cases.
Method injection is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean.
A proxy gets injected in place of the desired bean and provides that bean depending on the context. For example, if a singleton bean (such as a Spring MVC controller) auto-wires a session scoped bean, then the proxy delivers that bean belonging to the current HTTP session.
Such a proxy doesn't apply well to a situation where a prototype bean shall be obtained at runtime. Lookup method injection is one way to obtain prototype instances at runtime.
However, method injection has limitations because it builds upon abstract methods. Hence, certain things like writing unit tests are more cumbersome, as you need to provide a stub implementation of the abstract method. Component scanning doesn't work with abstract classes either.
One alternative to method injection is Spring's ObjectFactory, or its JSR equivalent Provider.
Another, straightforward way of creating prototype bean instances at runtime (which even makes it possible to provide constructor arguments) is to implement a bean factory like the following:
#Configuration
public class MyProvider {
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyThing create(String name) {
return new MyThing(name);
}
}
Usage:
#Component
public class MySingleton {
#Autowired
private MyProvider myProvider;
public void doStuffThatNeedsAPrototypeBeanInstance() {
MyThing thing = myProvider.create("some name");
...
}
}
For the question 1. When to use method injection and when to use aop-scoped proxy?
Let's say you have a singleton bean A has dependency on the prototype bean B. A has a method m which has B involved.
You got the object a of A and execute the method m several times. Every time m executing, a new object b of B needs to inject to a. That's the time you use the method injection.
Besides, if you have a singleton bean A has dependency on the session bean B. A has a method m which has B involved.
You got the object a of A and execute the method m several times. As long as the execution time is in a same session, a has the same object b of B. That's the time you use proxy.

how spring singleton scope for DAO class works internally

I went through some blogs and spring docs about the Spring singleton scope along with almost all spring singleton and DAO related question in stackoverflow.
I still do not have clear understanding of how the same object is injected to all the class which depend on it. I have learnt that the DAO needs to be stateless.
If the following DAO (sample dao having instance variable mainly to clear confusion) class is defined with default singleton scope and the same object is injected everytime, then there might be scenarios where department is null and therefore it won't set anything for department value instead use whatever the previous object value was.
public class UserDAO{
int userId;
Spring userDepartment;
// getter setter methods for userId and userDepartment
public boolean addUserToUserDetailsTable(int uId,
String name, String address, String department){
// set userId
userId = uId;
if(department!=null)
userDepartment = department;
// write code to add user to user table
// TO DO
// save user department data
addUserToUserDepartmentTable(userId, userDepartment);
}
public void addUserToUserDepartmentTable(int uId,
String department){
/* Code to save department data */
}
}
So if instead of using DI, if I manually call the DAO using new operator this problem won't be there.
new UserDAO().addUserToUserDetailsTable(id, "abc", null);
the above confusion generates following questions
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes. If this is true then how the previous object values from above DAO class is reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ?? Does stateless means the class cannot have instance variable.
does spring internally uses new object() to inject the beans.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
Please help me clearing the above confusion.
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes.
Yes, it's injecting a single instance, always the same, of the DAO class. That's the definition of singleton: a single instance is created.
If this is true then how the previous object values from above DAO class is reset.
It's not reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ??
Yes, the unique instance will hold the userId and department, since these are fields of the instance. You might run into problems trying to read and write these values, though, since they constitute shared mutable state, which is accessed concurrently from multiple threads without any synchronization.
Does stateless means the class cannot have instance variable.
In the strict sense, yes. But a DAO doesn't need to be stateless. It needs to be thread-safe, since the same instance is accessed from multiple threads concurrently. The best way to achieve that is to avoid having any state (so no instance variable). But this is hard to achieve for a DAO, which normally needs to have access to an injected DataSource, of JdbcTemplate, or EntityManager, or whatever. Since, however, these instance variables are normally injected by Spring during startup, before the DAO starts being used by multiple threads, and never written to during the lifetime of the application, that is thread-safe. Your code, however, has state, and the state is modified during the lifetime of the application, which makes it not safe.
does spring internally uses new object() to inject the beans.
It depends how the DAO bean is declared. It can be declared using JavaConfig, using a #Bean method calling the constructor. Most of the time, reflection is used to call the constructor. So there is no new MyDAO() in the code anywhere, but the constructor is still called (only once since it's a singleton), because that's the only way to create an instance of an object from scratch.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
That wouldn't be a singleton if it did that.
Singleton scope beans in Spring means one instance per container and the bean has to be stateless or else you will run into issues in cases of multi-threaded scenarios.
how is spring creating and injecting singelton beans, is it really
one and only one object which gets injected to all calling classes.
Spring creates once instance at startup and passes the same reference to all the calling objects which has requested for the same via Dependency injection.
If this is true then how the previous object values from above DAO
class is reset.
If your bean is stateless there would be no value held by the object, as most of the variable would be method local and not tied to the Instance object (DAO class in this case). However in your case since you have member variable tied to a class
all the classes which acquire this DAO bean would see the same value set to the member variable and this data will be be corrupted and is not recommended.
won't the instance variable hold their values here userId,
userDepartment if the same object is called from multiple class ??
Does stateless means the class cannot have instance variable.
Yes this the exact definition of bean being stateless. As explained above.
does spring internally uses new object() to inject the beans. or it
creates an object of DAO class and makes multiple clones of the
object, which i think is not possible because the DAO class is not
implementing clonnable.
If you have not defined the bean scope, by default spring would assume it is Singleton. The understanding of singleton scope and singleton pattern is different. Spring mimics singleton pattern by providing only instance but this does not stop you from creating new instance (using say new operator).
Your Singleton is not stateless. Userid and Department define the 'state'.
Spring creates one instance using reflection 'newInstance' or a producer function in your configuration.
This one instance is then provided to all objects requesting the DAO.
Your considerations are all valid but not resolved by spring: Since your DAO has a state, it is not properly implemented and results are undefined.
Answer to question 1: It is not reset. Spring won't handle state for you!
Basically (Q2) you are on a dangerous path if you use instance variables in stateless beans. The instance vars need to be stateless themselves, like other DAO singletons.
UPDATE: I want to elaborate on this. The singleton can have a state, but the state is shared between all users of the DAO. This does not strictly require your DAO to be thread safe: If you do not use threads, there is no concurrent use - but the state of a singleton is a shared state: All users of the singleton have the same. If you have two functions like so:
#Component
public class A {
#Autowired
DaoObject singleton;
#Autowired
B another;
public void aFunctionA() {
singleton.userId = "Foo";
System.out.printf("UserId: %s%n", singleton.userId); // prints Foo
another.aFunctionB();
System.out.printf("UserId: %s%n", singleton.userId); // prints Serviceuser
}
}
#Service
public class B {
#Autowired
DaoObject singleton;
public void aFunctionB() {
singleton.userId = "Serviceuser";
}
}
The state of the singleton singleton is shared between all users of the class. If one class changes the state, all other users have to cope with that.
If you are using threads, this adds extra complexity on stateful singletons, as your modifications to state must be thread safe.
It is common practice to keep a singleton immutable after initialization.
On your 4th question: Spring will not clone a Singleton, as described above.

Get Session in Spring AOP

I am no sure if my codes is thread safe,anyone can help?
#Aspect
public class MyAspect {
#Autowired
private HttpSession session;
#Before("...")
private void myMethod() {
seesion.getId();
}
}
Because MyAspect's scope is default(singleton),so many request exsits at same time and also many session.OK,Which session I get in my code?Is it thread safe?Or it's a wrong code,if it's wrong,how can I do?
Thanks!
Right, it's OK.
Your MyAspect should be registered as bean anyway.
It doesn't matter is it AOP Aspect or not: the dependency injection infrastructure the same.
Now about HttpSession.
This object isn't registered as bean, but for him Spring provide a trick - WebApplicationContextUtils.SessionObjectFactory. This object is registered as
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
And when the injection works it wraps SessionObjectFactory with Proxy to invoke real methods on demand from ThreadLocal<RequestAttributes> variable. That mean that each call of your MyAspect.myMethod does the stuff for concrete HttpSession, if your current Thread is a Servlet Thread, of course.
So, the answer to your question: yes, it is thread safe.

Initialize Singletons in Spring Framework 3 MVC

I am writing Spring 3.1.0 MVC based application. The problem is: i want to put some objects in a singleton object (current HttpServletRequest and HttpSevletResponse) to use them in other objects(Spring Controllers). But couldn't do so. I tried to extend DispatcherServlet, overriding both doService and doDispatch. Also tried to implement own HandlerInterceptor. No result.
Where can I initialize my singleton objects? And where is Spring Frameworks's entry point and destroy point (i.e. like init() and destroy() methods or lifecycle)?
The current HttpServletRequest and HttpServletResponse are available as method arguments to your controller methods:
#RequestMapping("/foo")
public String foo(HttpServletRequest request) {
}
I believe you can also #Inject them in your controller. A proxy will be injected, and each time you refer to them the current ones will be used. (I'm not 100% certain about this one)
A third option is to use the RequestContextHolder container, and get everything from there.

Difference between Stateless and Stateful session bean

I knew stateful beans maintain conversational session between different instance method call,but stateless will not.My question,assume I have a stateless bean implementation like below
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import com.tata.ejb3.data.HelloEJBInterface;
#Stateless
public class ValueEJB implements ValueEJBInterface{
private int value;
#Override
public int getValue() {
return this.value;
}
#Override
public void setValue(int value) {
this.value = value;
}
}
I have my bean client(A servlet) which initiates bean invocation as below
#EJB(mappedName="E/ValueEJB /remote")
ValueEJBInterface value;
....
value.setValue(250);
System.out.println(value.getValue());//This statement prints the value 250
....
According to my understanding as my bean is stateless bean it should not displayed with value 250.
private int value; is an instant variable,if one stateless method set its value , the value will be expired on method exit.But here, I am able to get the value '250' even via my second method call. Is it a violation of stateless concept? Am I lacking something?
Difference between Stateful v Stateless bean behavior when calling different methods.
STATEFUL: When calling different methods on a Stateful Bean, different bean instances are created.
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingStatefulThing();
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingNothingStatefulThing();
***Output: Note the creation of separate objects.***
INFO: Calling doingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#2fe395**
INFO: Calling doingNothingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#81cfcb**
STATELESS: When calling different methods on a Stateless Bean, the beans are pooled, hence no new instances of the bean are created.
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doSomething();
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doNothing();
***Output: Note the reuse of he bean object.***
INFO: Doing something ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
INFO: Doing Nothing ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
Interesting question and basically you are totally right. I did some research and the general advice is to: "Expect your bean to forget everything after each method call ..." (page 81). Furthermore, according to that resource, the algorithm responsible for maintaining the state of Stateless Session Beans is container / vendor specific. So the container may choose to destroy, recreate or clear the instance after method execution.
You could create a multi threaded test and see how it behaves with multpile clients.
There is no violation of any concept. Its because the same instance of bean is picked by the container from the pool to serve other request.
Stateless beans are pooled & therefore they have performance benefit over statefull beans, also their main purpose is processing without holding any state.
Sensitive or user specific data shouldn't be stored in instance variables of stateless beans. They should be used extensively to process data without any consideration of state.
Can refer here for their life-cycle events handled by the container.

Resources