Difference between a global variable and an injected variable? - java

Is it common practice to communicate via field references. Let's say I have an instance injected all over my program. Since all classes are referencing the same instance I can simply change it's state, instead of informing all dependent classes via method calls? Isn't that a big advantage of dependency injection? Or do I turn a dependency injected variable turn into a global variable?

Variables don't get injected. Values get injected. When you inject a bean into another bean you are injecting that reference. References are values, see
Is Java "pass-by-reference" or "pass-by-value"?.
You can have some spring bean in singleton scope that different parts of the application call, with some method which returns a value. For instance a spring boot application can have a Clock configured that various services or other components have injected into them, where they call the clock to get the current time.
If you do have a bean that contains some mutable value that gets set, be aware its scope will be limited to the application instance. If you have multiple instances of the application deployed. each one will have its own separate bean. Also changes aren't going to be guaranteed to be visible across threads unless you enforce that (with tools like locking, the volatile keyword, atomic variables, etc.).
Fundamentally OO is about message-passing, not about sharing memory. We want to limit global state because it's hard to reason about. Especially when you consider the high-concurrency of a web application and how quickly things can be changing, and how difficult it is to ensure changes are visible, in a lot of cases it's better to find alternatives to global variables.

Assuming that the injected type is configured to use a Singleton, there shouldn't be any behavioral difference between using dependency injection and accessing a Singleton directly.
The advantages to using Dependency Injection generally center around how the code is written, and how it allows you to decouple the consuming classes from the specific requirement for that injected object to actually be a singleton.
For example, if you want to unit-test your consuming class, you probably want complete control over what the class perceives as the current state, and you probably don't want any effects of the code your testing to carry over into other unit tests: you don't want a test to pass when it is run all by itself but fail if it happens to run immediately after some other test.
Using Dependency Injection, your unit tests can encapsulate the entire interaction with the code being tested. The code that instantiates the class has complete control over what gets injected, so it doesn't have to provide a singleton value.
By separating the class that consumes an injected value from any specific knowledge about where that value comes from, or what its life cycle looks like, you're better able to maintain separation of concerns. If a future change requires a value to no longer be a singleton (e.g. maybe it needs to be dependent on the current user), you're in a better position to change how that injected value is provided without having to change code all over your code base.

Related

JAX-RS Resource Lifecycle Performance Impact

I know by default JAX-RS endpoints lifecycle is once-per-request, so that the request specific informations can be injected into the instance.
And we can also make an endpoints Singleton meaning once-per-application, in which the request specific informations cannot be injected into the instance rather it can be injected into the requested method.
1. So i would like to know which approach is better in terms of performance, either once-per-request or once-per-application.
2. I would also like to know the pros and cons of these approaches other the injecting request specific informations
3. Which approach you prefer to use in your API applications
Note: i have been using the once-per-request approach so far, but i always wonder is that is efficient, definitely its make coding easier and reusable.
To start with your last question: I'm always using the default (per-request) and I seldom came to a point where I wanted to change this.
What might be a reason to prefer one over the other?
If you want to serve some static content (maybe a welcome-document of your API) it makes sense to produce this content only once and hold it in a singleton resource class. But you can achieve the same by e.g. injecting an #ApplicationScoped CDI bean in a per-request scoped resource class.
If you prefer injecting the #xxxParam values like #QueryParam as fields instead of method parameters you should use the per-request lifecycle. This is not supported for singletons. (This does not include injecting via #Context).
I made a little test to compare the performance of both. You can find the sources and the results on github. In short: I measured a difference from about 1.5 %. I don't think this should affect your application too much.
Comparing the results of the JVisualVM monitoring I would tend to say that the per-request test is using more memory but you should decide on your own if this really affects your application.

Is it a bad practice to use a ThreadLocal Object for storing web request metadata?

I am working on a j2ee webapp divided in several modules. I have some metadata such as user name and preferences that I would like to access from everywhere in the app, and maybe also gather data similar to logging information but specific to a request and store it in those metadata so that I could optionally send it back as debug information to the user.
Aside from passing a generic context object throughout every method from the upper presentation classes to the downer daos or using AOP, the only solution that came in mind was using a threadlocal "Context" object very similar to a session BTW, and add a filter for binding it on ongoing request and unbinding it on response.
But such thing feels a little hacky since this breaks several patterns and could possibly make things complicated when it comes to testing and debugging so I wanted to ask if from your experience it is ok to proceed like this?
ThreadLocal is a hack to make up for bad design and/or architecture. It's a terrible practice:
It's a pool of one or more global variables and global variables in any language are bad practice (there's a whole set of problems associated with global variables - search it on the net)
It may lead to memory leaks, in any J2EE container than manages its threads, if you don't handle it well.
What's even worse practice is to use the ThreadLocal in the various layers.
Data communicated from one layer to another should be passed using Transfer Objects (a standard pattern).
It's hard to think of a good justification for using ThreadLocal. Perhaps if you need to communicate some values between 2 layers that have a third/middle layer between them, and you don't have the means to make changes to that middle layer. But if that's the case, I would look for a better middle layer.
In any case, if you store the values in one specific point in the code and retrieve it in another single point, then it may be excusable, otherwise you just never know what side affects any executing method may have on the values in the ThreadLocal.
Personally I prefer passing a context object, as the fact that the same thread is used for processing is an artifact of the implementation, and you shouldn't rely on such artifacts. The moment you want to use other threads, you'll hit a wall.
If those states are encapsulated in a Context object, I think that's clean enough.
When it comes to testing, the best tool is dependency injection. It allows to inject fake dependencies into the object under test.
And all dependency injection frameworks (Spring, CDI, Guice) have the concept of a scope (where request is one of these scopes). Under the hood, beans stored in the request scoped are indeed associated with a ThreadLocal variable, but this is all done by the dependency injection framework.
What I would do is thus to use a DI framework, which would make request-scope objects available anywhere, but without having to look them up, which would break testability. Just inject a request-scoped object where you want to use it, and the DI framework will retrieve it for you.
You must know that a servlet container can / will re-use threads for requests so if you do use ThreadLocals, you'll need to clean up after yourself once the request is finished (perhaps using a filter)
If you are the only developer in the project and you think you gain something: just do it! Because it is your time. But, be prepared to revert the decision and reorganize the code base later, as should be always the case.
Let's say there are ten developers on the project. Everybody might like to have its thread local variable to pass on parameters like currency, locale, roles, maybe it becomes even a HashMap....
I think in the end, not everything which is feasible, should be done. Complexity will strike back on you....
ThreadLocal can lead to memory leak if we do not set null manually once its out of scope.

How to maintain a centralized Object across the application

I am developing an application where I need to create an object and multiple classes have to access and modify that object. How to see the recent changes made by the other class object and how to access the object centrally through all the classes with out passing that object as a parameter across all the classes?
I am creating an Apache POI document where I am adding multiple tables, multiple headers/footers and paragraphs. I want only a single XWPFDocument object present in my application.
Is there any design pattern we can achieve this?
Well the singleton design pattern would work - but isn't terribly clean; you end up with global static state which is hard to keep track of and hard to test. It's often considered an anti-pattern these days. There are a very few cases where it still makes sense, but I try to avoid it.
A better approach would be to use dependency injection: make each class which needs one of these objects declare a constructor parameter of that type (or possibly have a settable property). Each class shouldn't care too much about how shared or otherwise the object is (beyond being aware that it can be shared). Then it's up to the code which initializes the application to decide which objects should be shared.
There are various dependency injection frameworks available for Java, including Guice and Spring. The idea of these frameworks is to automatically wire up all the dependencies in your application, given appropriate configuration.
There is Singleton Pattern for this, it creates a single instance for the application and is shared without passing around.
But it not not the best of options.
Why is it a bad option?
It is not good for testability of code
Not extensible in design
Better than Singleton Pattern is an application wide single instance
Create a single object for the application and share it using some context object. More on this is explained by Misko in his guide to testable code
single instance and not Singleton Pattern
It stands for an application wide single instance, which DOES NOT inforce its singletonness through a static instance field.
Why are Singletons hard to test?
Static access prevents collaborating with a subclass or wrapped version of another class. By hard-coding the dependency, we lose the power and flexibility of polymorphism.
-Every test using global state needs it to start in an expected state, or the test will fail. But another object might have mutated that global state in a previous test.
Global state often prevents tests from being able to run in parallel, which forces test suites to run slower.
If you add a new test (which doesn’t clean up global state) and it runs in the middle of the suite, another test may fail that runs after it.
Singletons enforcing their own “Singletonness” end up cheating.
You’ll often see mutator methods such as reset() or setForTest(…) on so-called singletons, because you’ll need to change the instance during tests. If you forget to reset the Singleton after a test, a later use will use the stale underlying instance and may fail in a way that’s difficult to debug.

How to ensure a class can only be instantiated by Spring?

I am re-factoring a legacy Java application to use Spring.
This involves declaring the application classes as Spring beans and then replacing all occurrences of new with context.getBean OR with DI.
I'm re-writing application logic in way that some classes become singletons. However since they are being instantiated using new in other locations, multiple copies would exist which would mess up the business logic.
I'd like to ensure that application explicitly fails whenever it tries to instantiate an object by itself, instead of running and misbehaving in unpredictable ways. (I'm not sure that the re-factoring has covered 100% of the application there still might be new lurked up in some corner)
What is the best way of ensuring that a class can only be instantiated by Spring container?
(I'm hoping to avoid writing a factory for each class)
As from your question
In this particular scenario only one copy of an object should exist which is fetched from the context, multiple copies would mess up the business logic.
you can create classic singleton and use getInstance() method as factory method in bean definition in spring's xml file:
<bean id="myBean" class="MyClass" factory-method="getInstance"/>
Make your constructor private, and than no one can call it. Additionally you will see errors in compile time, if some parts of old code uses new to instantiate your class.

When would it be advised to use a ThreadLocal singleton instead of a request attribute?

If my ThreadLocal singleton is only going to be alive for the life of the request anyhow, then why not just use a request attribute? Is this just an easy way to get at a context in a single thread without having to pass through or get to the request object?
My opinion is, that using a request attribute is more preferable than using a ThreadLocal variable.
It makes code cleaner and you don't have to worry about cleaning the ThreadLocal (as it might be re-used be in context of another request which re-uses the same thread).
Though, properly designed and coded local request storage via ThreadLocal is fine, if usage of ThreadLocal is encapsulated and you don't simply share an instance between different classes (and it's life-cycle is properly handled).
In larger multi-tiered applications you don't generally want to be assuming that the scope of the work is a web request, or having dependencies on inherently 'web' things down inside the lower tiers. What if you execute this unit of work as a background job? Or it arrives via some legacy binary interface you end up supporting?
The drawbacks of using a ThreadLocal singleton are the same as the drawbacks of using a singleton in any other context. You lose encapsulation, re-usability, and the ability to mock out functionality.
The advantages are ease of use, type safety (no cast), and possibly performance (but probably insignificant in the overall scheme of things).
I would recommend against using a ThreadLocal singleton unless the functionality is well encapsulated and only accessed in very high level layers of the code (explicitly passing your context into deeper classes and functions instead of having them access the singleton).

Categories