Is scope=request good fit for high-load spring application? - spring

Is it common practice when singleton beans was injected to request-scoped beans, which injected to singleton-scoped beans?
For example, something like this:
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public class CurrentUser {
#Resource
private UserRepository userRepository;
...
}
public class ApplicationController {
#Autowired
private CurrentUser currentUser;
...
}
Is any overhead expenses for memory management possible? This implementation is tread-safe?
Thanks!

Essentially what is going to happen is that there will be an instance of CurrentUser for every active http request. The instances are managed behind a proxy created by Spring and the instance itself is maintained as a http request attribute and the lifecycle is tied to this request.
I would say that this is going to be costly in terms of the effort to instantiate and autowire each CurrentUser request instance. It should not be costly memory wise as the instances are short lived and scoped to request. On whether the instance is thread safe, yes it is.
One bug though, the proxyMode has to be ScopedProxyMode.TARGET_CLASS as your CurrentUser class does not implement any interfaces.

Related

Factory design pattern and Spring

I am wondering what is the current best practice as to the use of factory pattern within the context of Spring framework in using dependency injection. My wonder arises about whether the factory pattern is still relevant nowadays in light of the use of Spring dependency injection. I did some searching and see some past discussion (Dependency Injection vs Factory Pattern) but seem there is different view.
I see in some real life project in using a Map to hold all the beans and rely on autowiring to create those beans. When the bean is needed, it get it via the map using the key.
public abstract class Service {
//some methods
}
#Component
public class serviceA extends Service {
//implementation
}
#Component
public class serviceB extends Service {
//implementation
}
Map<String, Service> services;
But I see there is some difference among the two approaches.
Using the above method, all beans are created on application start up and the creation of object is handled by the framework. It also implies there is only one bean for each type.
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
The answer to this question can be really deep and broad, I'll try to provide some points that hopefully will help.
First off, spring stores its beans (singletons) in the ApplicationContext. Essentially this is the map you're talking about. In a nutshell, it allows getting the bean by name, type, etc.
ApplicationContext, while being a really important concept, is not the whole Spring, in fact Spring framework allows much more flexibility:
You say, using a map implies that all the beans will be created at the beginning of the application and there is one instance of the bean.
Spring has a concept of Lazy beans, basically supporting a concept of beans being actually created only when they're required for the first time, so Spring supports the "delayed" beans initialization
Spring also allows more than one instance of a bean per type. So this map is more "advanced". For example you can create more than one implementation of the interface and use declare both as beans. As long as you provide enough information about what bean should be injected to the class that might use them (for example with a help of qualifiers suppored in spring), you're good to go. In addition, there are features in spring IoC container that allow injecting all registered implementations of an interface into a list:
interface Foo {}
#Component
class FooImpl1 implements Foo {}
#Component
class FooImpl2 implements Foo {}
class Client {
#Autowired
List<Foo> allFoos;
}
Now you say:
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
Actually Spring can create objects per request. Not all beans have to be singletons, in general spring has a concept of scopes for this purposes.
For example, scope prototype means that Spring will create a bean upon each usage. In particular one interesting usage that spring supports in variety of ways is Injecting prototype bean into singleton. Some solutions use exactly like a factory (read about annotation #Lookup others rely on auto-generated proxy in runtime (like javax.inject.Provider). Prototype scope beans are not held in the application context, so here again spring goes beyond a simple map abstraction.
Last feature that you haven't mentioned is that sometimes even for singletons the initialization can be a little bit more complicated then calling a constructor with Parameters. Spring can address that by using Java Configurations:
#Configuration
public class MyConfig {
public SomeComplicatedObject foo(#Value("...") config, Bar bar) {
SomeComplicatedObject obj = new SomeComplicatedObject() // lets pretend this object is from some thirdparty, it only has no-op constructor, and you can't place spring annotations on it (basically you can't change it):
obj.setConfig(config);
obj.setBar(bar);
return obj;
}
}
The method foo here initializes the object SomeComplicatedObject and returns it. This can be used instead of factories to integrate "legacy" code (well, java configurations go way beyond this, but its out of scope for this question).
So bottom line, you Spring as an IoC container can provide many different ways to deal with object creation, in particular it can do everything that factory design pattern offers.
Now, I would like to also refer to your last sentense:
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
Indeed you don't have to use Factory Pattern when using Spring, since (as I hopefully have convinced you) provides everything that factory can do and more.
Also I agree that spring is supposed to be the central handler of the objects dependency (unless there are also parts of the application which are written in a different manner so you have to support both :) )
I don't think we should avoid using "new" altogether, not everything should/can be a bean, but I do see (from my subjective experience, so this is arguable) that you use it much less leaving the creation of most of the objects to Spring.
Should we avoid a usage of any creation design pattern? I don't think so, sometimes you can opt for implementing "builder" design pattern for example, its also a creational pattern but spring doesn't provide a similar abstraction.
I think if your project uses Spring framework you should use it. Although it depends on your project design e.g. You may use creational patterns along side with Spring IoC. e.g when you have abstraction layers not framework dependant (agnostic code)
interface ServiceFactory {
Service create(String type);
}
#Component
class SpringServiceFactory implements ServiceFactory {
#Autowired private ApplicationContext context;
Service create(String type) {
return context.getBean(type)
}
}
I use Factory pattern as well when I refactor legacy not unit testable code which also uses Spring Framework in order to implement unit tests.
// legacy service impossible to mock
class LegacyApiClient implements Closeable {...}
#Component
class LegacyApiClientFactory {
LegacyApiClient create(String endpoint) {
return new LegacyApiClient(endpoint);
}
}
#Component
class OtherService {
private final String endpoint
private final LegacyApiClientFactory factory;
OtherService(#Value("${post.endpoint}") String endpoint,
LegacyApiClientFactory factory) {...}
void doCall {
try (LegacyApiClient client = factory.create(endpoint)) {
client.postSomething();
}
}
}
....
// a random unit test
LegacyApiClient client = mock(LegacyApiClient.class)
LegacyApiClientFactory factory = mock(LegacyApiClientFactory.class)
OtherService service = new OtherService("http://scxsc", factory);
when(factory.create(any())).thenReturn(client)
service.doCall()
....

Bean with singleton scope and with states

I know there are already tons of questions on this. But they don't clarify my doubts.
It is recommended here that to achieve thread safety, design your beans stateless. I don't understand it.
If I have a service class and it has only one state in it (and no other instance variables).
#Service
class MyService {
#Autowired
MyRepository repository;
//business method that call repository methods
}
MyRepository has a default singleton scope. It has org.springframework.data.mongodb.core.MongoTemplate autowired. And that's the only instance variable I have in MyReporitory.
#Repository
class MyRepository {
#Autowired
MongoTemplate mongo;
//methods that use MongoTemplate reference
}
So what is the deal here? Is service/repository thread safe?
If your repository reference is immutable (only autowired once, or set during service object construction) then your service bean is thread-safe.
Generally speaking, when multiple threads access the state of a bean simultaneously and that state is mutable (can change) you have potential threading issues. If the state is immutable and it's being read by multiple threads you need not worry about multi-threading issues.

spring annotation manage pojo

I use spring annotation to manage java bean, use #service in service layer, and #autowired when inject service, but now I have a question, how to manage POJO by spring?
for example, I need to return a user for ajax call, so I need to always write like:
User user = new User()......
return user;
So, how I can use like
#autowired User user;
And the User POJO will be:
#component
#scope("prototype")
public class User{}
so each time the user entity will be a new one, and I needn't to new it everytime,
But I failed to write like this, so can spring manage POJO to be a prototype?
Update====================================
Thanks for answering
You have three options that i can think of straigh away. What you want is to be able to create prototypes from within a singleton. So you can either use..
1) AOP Scoped Proxy.
So change your User class annotation to ...
#Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
(this required cglib on your classpath)
or
2) lookup-method
this is a bit more involved and makes things a bit harder to test
or
3) make your class implement ApplicationContextAware and then you can just call getBean on the context when you want a new prototype.
A bit of googling will sort you out anyway but I recommend the first option
Try following code:
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class User
{
......
}
Hope it helps.

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.

Spring AOP and aspect thread safety for an autowired HTTPServletRequest bean

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.

Resources