I have a jax-ws web service with several handlers. I have a particular object that is performance wise costly to initiate. I need this object to process each and every request come to web service.
Is it a solution to put this object to a static block? Since static block is created at class loading time will it give a performance improvement. But still does it achieve what I need. I need same object kept in the memory and reused for all requests. But as I know in a web service each request is allocated to a thread object in the static block will not be shared by threads. it is?
Expecting a bit of explanation here guys.
Thank you
A static block is a piece of code which is run once when the class is initialized by the class loader. You might use it to set up your complex object and then keep a reference to it in a static variable like so:
public class MyClass {
private static final LanguageLookup languageLookup;
static {
languageLookup = new LanguageLookup ();
languageLookup.loadData();
}
public Response handleRequest(Request request) {
String language = languageLookup.lookup(request.getCountryCode());
response.setLanguage(language);
return response;
}
}
If you do this in a multi-threaded environment like a servlet or a webservice you need to be sure that the state of LanguageLookup cannot change after its initialization. If it uses dependencies of its own for operations other than its initialization, these must also be stateless.
I think it is generally not a good idea to do it this way because you are hard-wiring your class to the LanguageLookup, making it tightly coupled and harder to unit test.
It is very easy to use a dependency injection framework like Spring to set up singletons:
When a bean is a 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.
In the application context you would have something like:
<bean name="languageLookup" class="com.acme.foo.LanguageLookup" singleton="true" init-method="loadData"/>
And in your code:
public class MyClass {
private LanguageLookup languageLookup;
public Response handleRequest(Request request) {
String language = languageLookup.lookup(request.getCountryCode());
response.setLanguage(language);
return response;
}
// called by Spring
public void setLanguageLookup(LanguageLookup languageLookup) {
this.languageLookup = languageLookup;
}
}
Related
Is there a way to autowire an object that needs to be re-instantiated frequently?
I am using Netflix's DGS + spring boot framework, and basically storing the user authentication details in a custom context which is created for each request. I am trying to avoid adding context to the method signature because of the large amount of refactoring needed.
e.g.
public Result dataFetcher(DataFetchingEnvironment dfe) {
// this context contains user details which is used for authorization
// instantiated for every request
setRolesInContext(dfe);
MyCustomContext context = DgsContext.getCustomContext(dfe);
// trying to avoid adding context as an extra param e.g. dataFetcherHelper(context)
dataFetcherHelper(); // this calls other helper methods from other classes
}
I was thinking of using the facade pattern but this would not be thread safe. Basically autowire the RequestContextHolder, and call setRequestContext each time a new context gets initialized.
#Component
#NoArgsConstructor
#Getter
#Setter
public class RequestContextHolder {
private RequestContext requestContext;
}
I'm not sure how your question:
Is there a way to autowire an object that needs to be re-instantiated frequently?
Is related to the use case that you've presented in the question...
From the question it looks like you can consider using ThreadLocals as a conceptual "substitution" to the global variable available all over the place in the request if you don't want to add parameters to the methods to propagate the context through the flow.
This will work only in "thread-per-request" model, it won't work for reactive systems and for the complicated cases where you maintain different thread pools and switch the threads while implementing the Business Logic on backend:
So to achieve "thread-safety" in your context holder that you have suggested you can use:
#Configuration
public class MyConfig {
#Bean
public ThreadLocal<MyCustomContext> ctxHolder() {
return new ThreadLocal<>();
}
}
Then, again, if you're working in thread-per-request model, you can:
#Component
public class DataFetcherInterceptor {
#Autowired
private ThreadLocal<MyCustomContext> ctxHolder;
public Result dataFetcher(DataFetchingEnvironment dfe) {
// this context contains user details which is used for authorization
// instantiated for every request
setRolesInContext(dfe);
MyCustomContext context = DgsContext.getCustomContext(dfe);
ctxHolder.set(context);
dataFetcherHelper();
}
}
In the dataFetcherHelper or in general in any method that requires the access to the context you can:
public class SomeService {
#Autowired ThreadLocal<MyCustomContext> ctxHolder;
public void dataFetcherHelper() {
MyCustomContext ctx = ctxHolder.get();
}
Now, I see that dataFetcherHelper is just a method that you call from withing this "interceptor" class, in this case its an overkill, but I assume, you've intended that this is actually a method that belongs to another class, that might be an element in the call-chain of different classes. For these situations, this can be a working solution.
I have a Spring MVC web application (XML based without annotations). I want to create only one instance of statsDClient object on start of my application and use it across my whole application. I am trying something like below:
import com.timgroup.statsd.NonBlockingStatsDClient;
import com.timgroup.statsd.StatsDClient;
Public class Helper(){
private static final StatsDClient statsDClient = new NonBlockingStatsDClient("prefix", "localhost", 8125);
private Helper(){}
public static StatsDClient getInstance() {
return statsDClient;
}
}
Later in my controllers I am getting the statsDClient object in the following way:
public class HelpController extends AbstractController {
private StatsDClient statsDClient = Helper.getInstance();
protected ModelAndView handleRequestInternal(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
statsDClient.someMethod();
}
But, this seems to be creating creating a new statsDClient object everything I use it in different controllers. Can you please guide where am I going wrong?
Variables that marked static was created only once in memory. You can create a bean and inject it wherever you need.
Beans in spring is by default singleton, which means only one shared instance is ever created and being managed by the spring container through out the entire application.
So in your case, you don't need to specify statsDClient to be a single instance,
you could do something like
to ensure statsDClient would have been instantiated once only
but it's just redundant
Pls refer to https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/htmlsingle/#beans-factory-scopes-singleton for better understanding
I Have this class:
package ds;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import play.mvc.Http;
public class MyRoutingDataSource extends AbstractRoutingDataSource {
#Override
protected String determineCurrentLookupKey() {
return Http.Context.current().session().get("currentDB");
}
}
But when I want to access into the Play session I have this error:
Caused by: java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:34) ~[play_2.10-2.3.10.jar:2.3.10]
at play.mvc.Controller.session(Controller.java:72) ~[play_2.10-2.3.10.jar:2.3.10]
I also tried with HttpExecution.defaultContext() and his HttpExecutionContext but it cannot be cast to the Http.Context that is what I need.
I was thinking about get the request header but certainly I don't know how to handle it from my class and determine the session from the request
You can't access the Play Context in that tier cause is out of scope. In the documentation of the AbstractRoutingDatasource:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html
The main description of the class says:
Abstract DataSource implementation that routes getConnection() calls
to one of various target DataSources based on a lookup key. The latter
is usually (but not necessarily) determined through some
thread-bound transaction context.
So this class is suggesting that a way to get information of the current context should be using a Thread-Bound Transaction Context.
Now, Is PlayFramework Thread Context Safe? Reading Play documentation:
https://www.playframework.com/documentation/2.3.x/ThreadPools#Java-thread-locals
Java code in Play uses a thread local to find out about contextual
information such as the current HTTP request. Scala code doesn’t need
to use thread locals because it can use implicit parameters to pass
context instead. Threads locals are used in Java so that Java code can
access contextual information without needing to pass context
parameters everywhere.
So, if you are using a Java implementation, you can use ThreadLocals as context channel between components. Be careful if you create your own thread pools because there's a warning in the same documentation:
The default objects wrap the default user thread pool. If you want to
do your own threading then you should use the HttpExecution class’s
helper methods to get an ExecutionContextExecutor object yourself.
But that won't be a problem if you are not using custom thread pool in your app.
Said that, what you have to do is:
Define a ThreadLocalContext for the object that you want to use as router.
Put in the context. (You can do it in the controller, in the security controller if you are using an authorization framework like Deadbolt or even implementing a new request filter.)
Reading in the AbstractRoutingDataSource the ThreadLocal context.
Important! Don't forget to clean the Thread-Local or you can face a memory Leak.
Step 1:
public class RequestContext {
private static final ThreadLocal<String> contextHolder =
new ThreadLocal<String>();
public static void setRoutingKey(String key) {
contextHolder.set(key);
}
public static String getRoutingKey() {
return (String) contextHolder.get();
}
public static void clearRoutingKey() {
contextHolder.remove();
}
}
Step 2:
//Demostrative code, not tested, not even compiled
public static void myController() {
RoutingContext.setRoutingKey(Play.Context.request());
return bla;
}
Step 3:
#Override
protected Object determineCurrentLookupKey() {
String datasource = RoutingContext.getRoutingKey();
RoutingContext.clearRoutingKey();
return datasource;
}
Regards!
I have a jsp application (using Spring) that uses a couple of global variables. I need multiple people to be able to use this program concurrently, however. What is the best way to go about making it thread-safe such that each instance of the program is independent of the others?
::EDIT:: Am I okay if I just don't use any singleton objects?
Each request is handled in its own thread. These threads are managed by the servlet container. It is not a good idea to use static global variables in a servlet. All instance variables are common to all threads, therefore it can lead to ambiguous state.
I recommend saving this type information in a scope variable (application,session, request, page, etc).
If you have to use a global variable then you will need to synchronize the access to it to avoid unknown states.
A typical container uses a thread-per-request model, so you have an easily-recognizable boundary built right in. The general rule is to never store any state in any object that is visible to multiple requests (threads) unless that state is effectively immutable. For example, a singleton controller like this
#Controller
#RequestMapping("/schedule")
class MyController {
private Scheduler scheduler;
#RequestMapping(method = RequestMethod.POST)
public void scheduleSomething(Foo foo) {
scheduler.schedule(foo);
}
}
is stateful--the schedular field holds state--but the state is initialized at startup and remains constant across all requests/threads. If you had a singleton controller like this, on the other hand:
#Controller
#RequestMapping("/schedule")
class MyController {
private Scheduler scheduler;
private Foo foo;
#RequestMapping(method = RequestMethod.POST)
public void scheduleSomething(Foo foo) {
this.foo = foo;
scheduler.schedule(this.foo);
}
}
That is absolutely not safe for concurrent access because all requests go to this same controller, and foo will be constantly changing in a non-thread-safe way. Follow this line of reasoning through your entire application, and you'll be safe.
I am converting a singleton to a Spring bean, so that if the singleton fails to initialize, then entire web application's spring context doesn't load properly.
The advantage of making the Spring context not load properly, is that people will take notice and fix the configuration during deployment itself. As opposed to using 'non-spring bean' singleton: when that throws exception during initialization, nobody notices.. until a actual user complains of missing functionality.
My changes are working as expected.. but I am not sure if I am doing the right thing.
Any thoughts?
The code looks like this:
public class MySingleton {
private static MySingleton INSTANCE = null;
private MySingleton(){}
public static MySingleton getInstance(){
if(INSTANCE == null){
synchronized(MySingleton.class){
if(INSTANCE == null){
try{
doWork()
}catch(Exception e){
throw new IllegalStateException("xyz", e);
}
INSTANCE = new MySingleton();
}
}
}
return INSTANCE;
}
private static void doWork() {
// do some work
}
}
And in the spring config xml, the bean will be defined as:
<bean id="MySingletonBean"
class="com.MySingleton"
factory-method="getInstance" lazy-init="false" singleton="true">
</bean>
Note:
Most of this is similar to the strategy discussed in this article:
http://springtips.blogspot.com/2007/06/configuration-hell-remedy-with.html
Edit 1:
The classes that use this singleton, are not spring beans themselves.. they are just non-spring pojos, that I can't convert to spring. They must rely on getInstance() method get hold of the Singleton.
Edit 2: (copying a comment I made below into this description section)
I am trying to target two things:
I want Spring to initialize the singleton. So that if the
initialization fails, then the application loading fails.
I want the other classes be able to use classes without having to rely on contextAwareObj.getBean("MySingleton")
EDIT 3 (FINAL):
I decided to make this class a singleton.. and am not making it a spring bean. If it fails to initialize, it will log something in the Log file.. hopefully the person doing deployment takes notice.... I abandoned the approach I mentioned earlier because I feel it will create a maintenance nightmare in future, so I had to pick between - singleton - or - spring bean. I chose singleton.
You must declare the INSTANCE field as volatile for double-checked locking to work correctly.
See Effective Java, Item 71.
Why are you using singleton pattern on the first place? Just let Spring create bean for you (with default singleton scope) and... use it. Of course always somebody might create the bean by hand, but this was never a problem in my case.
Dependency injection and Spring-managed bean lifecycle will ease your life significantly (just see how many pitfalls you can avoid). Also note that exceptions thrown from c-tor or #PostContruct method will propagate and cause application context startup to fail as well.
UPDATE: I get your point. This is what came in to my mind:
#Service
public class Singleton {
private static AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();
public Singleton() {
final Singleton previous = INSTANCE.getAndSet(this);
if(previous != null)
throw new IllegalStateException("Second singleton " + this + " created after " + previous);
}
public static Singleton getInstance() {
return INSTANCE.get();
}
}
And let Spring do its job. You can use DI when possible and Singleton.getInstance() where you have to.
Also there are more hard-core solutions like compile-time AspectJ weaving and injecting Spring beans basically to everything.
I'm not sure why you'd want to do this. When you tell Spring that a bean should be a singleton, the corresponding class does not need to be a singleton, and does not need a factory. Spring just simply only ever creates one instance.
The linked article makes no sense to me, since there is NO injection happening, that I can see: "AnyService" is calling the singleton factory method; that the singleton is referenced in the app context is irrelevant until it's referenced, and it seems no other bean references it.
True singleton are hard to get working.
Volatile double-checked locking also does not work property. Read about it on wiki http://en.wikipedia.org/wiki/Double-checked_locking
Your best bet is to simply do this
public class MySingleton {
private static MySingleton INSTANCE = new MySingleton();
That is if you do not have any constructor parameters in your real code.
According to me this is a belts-and-suspenders solution.
If you create a bean and declare it as a singleton in the configuration then there should be no need to protect the bean against being multiply created.
You are now basically protecting yourself from someone wrongly configuring the bean.
I personally would "solve" that by documentation in the spring configuration and Javadoc.
To run code at startup (and fail on error) use one of the many ways to register startup events, e.g. see http://www.baeldung.com/running-setup-logic-on-startup-in-spring
Example:
#Component
public class InitializingBeanExampleBean implements InitializingBean {
private static final Logger LOG = Logger.getLogger(InitializingBeanExampleBean.class);
#Autowired
private Environment environment;
#Override
public void afterPropertiesSet() throws Exception {
LOG.info(Arrays.asList(environment.getDefaultProfiles()));
}
}
#Component
public class SingletonDAOImpl {
}
#Component
public class SingletonDAO {
#Autowired private SingletonDAOImpl instance;
public SingletonDAOImpl getInstance(){
return this.instance
}
}
public class WhateverPlaceYouNeedIt{
#Awtowired private SingletonDAO singletonDao;
public void useSIngleton() {
SingletonDAOImpl INSTANCE = singletonDao.getInstance();
}
}
I tried in so many ways to do something like SingletonDao.instance.doSomething()
but just is not in the spring way and you will find so many hacks in order to do this but is incorrect in my opinion
here
You have your Singleton, which can be changed after in a Multiton
For sure is a single implementation
is respecting the INSTANCE pattern as "getInstance"
Is in-memory so each time is the same object as in singleton
is the same principle applied slightly different, very simple, all the time try to KIS implementation(Keep it simple)