Are autowired objects in spring-mvc threadsafe? - spring

Question 1) From my understanding spring creates singletons objects, So when I have a controller like below with a autowired service, will that affect threadsafety.
Question 2) If I declare a int type variable at class level and use it in controller or service, will it affect thread safety?
#Controller
public class LoginController {
#Autowired
public DaoService daoservice;
#RequestMapping("/")
public String getBookInfo() {
Book book = daoservice.getBookbyId(1L);
System.out.println(book.getTitle());
return "welcome";
}
}
#Service
public class DaoService {
#Autowired
public BookRepository BookRepo;
public Book getBookbyId(Long Id) {
Book book = BookRepo.findOne(Id);
return book;
}
}

Q.1 : Are Spring Beans Thread Safe?
Answer: No.
Spring don't give you thread safety for their bean. Spring provide different type of bean scope like (Prototype,Singleton etc). If Prototype then a new bean create each time it invoke where a singleton bean created for one time and shared in application context.
If you are thinking for HTTP request, then 2 or more request can come.Hence new instance of a bean is created in each request scope. So you can think they are thread safe in context of HTTP request but it's not truly thread safe by spring itself.Because several thread can share the bean within the same HTTP request context.
Q.2 : Are Class variable Thread Safe?
Answer: No
Quoted from here
All private member variables are shared. They might be final, but that only means that the references can't be changed. Any mutable state must be synchronized.

Related

Spring Instantiate a component dynamically inside a method

I'm trying to instantiate a component inside a method, to be more precise inside a rest method. I need a new instance of the component every time the rest method is invoked
#Validated
#RestController
#RequestMapping("test")
public class Test {
#GetMapping
public String test() {
// Spring equivalent of
// TestComponent component = new TestComponent();
return component.uuid();
}
}
My component is defined like this
#Scope
#Component
#Transactional
public class TestComponent {
private EntityManager entityManager;
private UUID randomUUID;
#Autowired
public TestComponent(EntityManager entityManager) {
this.entityManager = entityManager;
this.randomUUID = UUID.randomUUID();
}
public String uuid() {
// entityManager transactional stuff
return randomUUID.toString();
}
}
I tried to use a factory method but the instance was not transactional, I tried to use ApplicationContext.getBean but the instance was a singleton. How can I instantiate my component dynamically whenever I need it?
I'm using Spring 3.0.0-RC1
You can use different scopes to define the life cycle and visibility of that bean in the context. The default scope is Singleton, which means only one instance is created.
In your particular case, I think that you should choose between:
Prototype - creates a new instance every time a request for that specific bean is made. It can be defined with #Scope("prototype") annotation.
Request - each HTTP request has its own instance, only valid in the context of a web-aware Spring ApplicationContext. It can be defined with #RequestScope annotation.
To find out more details about all supported scopes, check the documentation.

Spring boot controller structure (dependency injection problem)

There is something I want to do structurally while creating a controller.
Is it ok to implement #autowired as below?
#Controller
class myController{
#autowired
MyComponent1 myComponent1;
public void myfunc(){
myComponent1.init();
myComponent1.excite();
}
}
I am wondering if myComponent1, created in a singleton, is not a problem with concurrency.
If lock myfunc, it will be too slow.
#Controller
class myController{
public void myfunc(){
Mybeen mybeen = SpringApplicationContext.getBean("myComponent1", myData);
mybeen.init();
mybeen.excite();
}
}
#scope("prototype")
#Component("myComponent1")
class myComponent1{
~~~~~~~~~~~~~~~~~~~~~~~~
}
#Component, but it gives #scope (prototype) to work on a new non-singleton object.
However, there is a problem in that it creates a new myComponent1 object for every request.
Question 1.
Which way is right? Is there any other way?
Question 2.
If #Component has #scope ("prototype"), is it not different from the object created by new, not Component?
Question 3.
Each request is handled by a new thread. I do not need to create a thread pool in that structure, right?

Injecting dependencies using an Interceptor

Would it be technically a good and acceptable practice to inject required dependencies using an Interceptor type. For example:
public #interface Inject {
public Class thisType();
}
public class InjectionInterceptor implements HandlerInterceptor {
#Override
public bool preHandle(HttpServletRequest hsr, HttpServletResponse hsr1, Object o) {
HandlerMethod handlerMethod = (HandlerMethod) o;
Class type = handlerMethod.getBeanType();
Annotation[] annotations = type.getAnnotationsByType(Inject.class);
for(Annotation annotation: annotations){
Inject inject = (inject) annotation;
for(Field field :type.getDeclaredFields()){
if(field.getType().equals(inject.thisType())){
field.setAccessible(true);
field.set(handlerMethod.getBean(), Services.find(inject.thisType()));
}
}
....
return true;
}
...
}
A bean can have 4 scopes.
Singleton
Only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
It is default scope of a bean.
Prototype
New instance is returned by the container when bean with the specified id is requested.
Ex: If you have a bean with id as "employee" in your spring container, then everytime you do a
Employee emp = context.getBean("employee");
A new instance will be returned.
request, session, and global session are for use only in web-based applications
Request
A new instance is created for every single HTTP request.
Ex : Login needs different instance everytime.
Session
A new instance will be created of the bean using the bean definition for the lifetime of a single HTTP Session.
global
The global session scope is similar to the standard HTTP Session scope and really only makes sense in the context of portlet-based web applications
You can specify the scope of a bean in two ways
Using XML:
<bean id="employee" class="com.company.Employee" scope="singleton"/>
Using annotation.
mark the class with #Scope("prototype")
you can read more about scopes here
sample code for reference is available here

Is this Spring bean stateless?

Is the below bean stateless and therefore thread-safe? More specifically my consern are the injected values the String array. Does this interfere with the state of the bean? NO right?
public class ServiceImpl implements Service {
private static final Logger LOG = Logger.getLogger(ServiceImpl.class);
/* Injected values properties file. */
private String[] values;
#Autowired
private DAO dao;
#Transactional
#Override
public void invoke(String submissionId) {
dosomething....
}
}
The main question to ask here is
What is a stateless object ?
The answer is that your Object is stateless if its properties does not change during its lifetime. I assume your bean is scoped as a singleton and therefore, as long as the values property does not change during the lifetime of your bean it is stateless. Otherwise not.
It is stateless, if there is no write access to the values array. Otherwise, you will probably run into errors.
If you do not modify the properties (or the properties of the objects refered by your bean) after initialization, the bean is effective stateless. No matter what kind of type you use.
So if you do not modfiy the array or one of its items, you bean is effective stateless/ effective immutable.

How can I make sure a "pool" bean gets all the other beans it needs?

I have a spring config where I define hundreds of actions which extend MyAction. I have a pool where an execution service can look up actions. I can't use the appContext directly because each action has one or more "keys" which the execution service will use and pool cuts that dependency.
So the pool must be able to collect all beans of type MyAction (or rather beans that extend MyAction).
The method ApplicationContext.getBeansOfType() seems to do what I need but when can I safely call it?
It would be great if I could call it in a #PostConstruct method but is it guaranteed that the bean factory has seen added each and every bean from the config at that time?
Note: Almost all of my beans are #Lazy
You could use injection by constructor and passing a Collection of yours MyAction
Something like
#Component
public class Foo {
private final Set<MyAction> myActions;
#Inject
public Foo(Set<MyAction> myActions) { this.myActions = myActions; }
}
or
public class Foo {
private Set<MyAction> myActions;
#Inject
public void setMyActions(Set<MyAction> myActions) { this.myActions = myActions; }
}
Spring will take care of creating the set with all beans that extends MyAction.
In the first case, they are injected by constructor, you can safely use them in any method.
In the second case, Spring will eventually call the setter. You can either do any post processing in the setter or add a #PostConstruct method that works on myActions.
Try to use ListableBeanFactory like this. Also here is API documentation. Method getBeansOfType has parameter allowEagerInit which forces eager init of lazy object.

Resources