Singleton Use - How to make Data Available to all Classes? - java

I have created a singleton class using the following code:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
I now want to make data from my program available to all of my classes using this singleton class (any suggested modifications are more than welcome). How do I proceed to do so?

Well now you can initialise your Singleton with data in your constructor, or you can add methods to your Singleton class to get data.
Then you'll just have to import the Singleton class in your other classes and get your instance with getInstance().
If you want to look into a more up to date way of accessing data from multiple classes, you could take a look into dependency injection.

Related

Guice - Is there a way to inject a new instance of a dependent object into a Singleton?

I have a class that has been configured to be a Singleton, like this:
#Singleton
public class MySingleton {
public MySingleton(MyDependency dependencyObj) {
// ...
}
}
Is there a way to get a new instance of MyDependency injected into the single instance of MySingleton each time Guice provides it to some other class?
I can't make any changes to MySingleton (e.g., to make it something other than a Singleton)

Guice. Inject into constructor

I have a singleton:
public class MySingleton{
public static getInstance(){//typical singleton getInstance
...
}
//fields
private static volatile instance;
#Inject
private AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla;
private MySingleton(){
...
anotherClassInst_BlaBla.doSmth();//NullPointerException happens!
...
}
}
What is cause of this NPE? Does it happens because it is constructor or because it is singleton?
When the constructor of MySingleton is invoked, instance is null. Guice has to construct the instance of MySingleton before it has anything to inject into.
Guice has a concept of singletons: either you bind the class in singleton scope in your module, or you annotate the class as #Singleton. Then you just inject like usual:
#Singleton
public class MySingleton {
private AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla;
#Inject public MySingleton(AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla) {
this.anotherClassInst_BlaBla = anotherClassInst_BlaBla;
anotherClassInst_BlaBla.doSmth();
}
}
anotherClassInst_BlaBla is an instance variable in this case, I guess that's why you choose setter injection. Since it's an instance variable and also setter injection needs an instance to set this variable to, an instance of MySingleton class needs to be created/constructed to use anotherClassInst_BlaBla.
Shortly, you should call doSmth() method after the constructor MySingleton() is invoked because setter injection happens after an instance is constructed.

Performance: Utility class vs. CDI bean

I want to externalize commonly used applicationlogic into a "utility class" called Helper. The applicationlogic needs other CDI beans to work.
Two possibilities:
a)
#SessionScoped
class ControllerWithCdiBean {
#Inject
Helper helper;
public void doIt() {
Object result = helpder.calculate();
}
}
#RequestScoped
class Helper{
#Inject
Service anyService;
public Object calculate() {
return anyService.calc();
}
}
b)
#SessionScoped
class ControllerWithStaticCallsViaDeltaspike {
public void doIt() {
Object result = Helpder.calculate();
}
}
class Helper{
private static Service anyService = BeanProvider.getContextualReference(Service.class);
public static Object calculate() {
return anyService.calc();
}
What about performance? Are there any notable differences? Both solutions are possible for me, is one solutions better than the other?
One disadvantage:
Helpder gets initialized for every Request.
Mark your Helper class as #ApplicationScoped. With this, you will have a single instance per application context.
Still, if it's just an utility class, it shouldn't be a managed bean at all. I would instead mark it as final, define a private constructor and mark all the methods as static. This is because since it's an utility class, it doesn't need to maintain any state.

Singleton lazy vs eager instantiation

If a singleton is implemented as follows,
class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
How is this implementation different from the lazy initialization approach?
In this case,the instance will be created when the class is loaded and the class itself is loaded only on the first active use (for example, Singleton.getInstance() not when you declare for instance Singleton singleton = null;)
Even with lazy initialization approach, the instance is created on the call to getInstance()
Am i missing something here?
With lazy initialization you crate instance only when its needed and not when the class is loaded. So you escape the unnecessary object creation. That being said there are other things to consider too.
In lazy initialization you give a public API to get the instance. In multi-threaded environment it poses challenges to avoid unnecessary object creation. you put synchronization blocks which poses unnecessary locking to be done to check for object already created. So it becomes a performance issue in this case.
So if you are sure that creating you object is not going to take any significant memory and its almost always going to be used in your application then its good to create in static initialization. Also please do not forget to make your instance final in this case as it make sures that the object creation is reflected properly and in totality to main memory which is important in multi-threaded environment.
Please refer this tutorial from IBM on Singleton+ Lazy Loading+ Multithreaded Environment case
===============Edit on 09/09/2018====================
You should also look at object creation on demand pattern here.
You may call any other static methods or static member variable too to load the singleton instance.
class Logger {
private static Logger instance = new Logger();
public static String LOG_LINE_SEPERATOR =
System.getProperty("line.separator");
public static Logger getInstance() {
return instance;
}
public static String logPattern() {
return null;
}
}
...
Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
For the reasons you mention, this is just a more complicated way of doing much the same as
enum Singleton {
INSTANCE;
}
Using lazy initialisation is only useful if you are concerned that the class could be initilised but you don't want to load the singleton at that point. For most situations this is over kill.
Note: Just referencing the class does not initialise the class.
e.g. Say you have a badly written class which cannot be initilised until some condition is set. In this case n must be non-zero.
public class Main {
public static void main(String ... args) {
Class c= LazyLoaded.class;
System.out.println(c);
}
static class LazyLoaded {
static int n = 0;
static {
System.out.println("Inverse "+1000/n);
}
}
}
prints
class Main$LazyLoaded
First of all, the singleton pattern is overused. What you really want to do if you want "one of something" is to declare it a singleton in your DI framework of choice. This is effectively a configuration driven eager singleton, and frees up options for injecting mocks to do proper testing.
Why not lazy load? Unless your class has a massive initialization routine in construction (which I would argue is also an anti-pattern), there is no benefit and lots of drawbacks to lazy loading. You're just adding complexity and possibly breaking your program if it's not done correctly. The correct way (if you must) is to use the Initialization-on-demand holder idiom.
For lazy loading singleton instance, I am using as below.
class Singleton {
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if(null==instance){
synchronized(Singleton.class){
if(null==instance){
instance = new Singleton();
}
}
}
return instance;
}
}

how to change the attribute value using reflection

is it possible to change the value of an attribute of a class using reflection.
below is my class :-
public class LoggerManager {
private static LoggerManager _instance = new LoggerManager();
private LoggerManager() {
}
public static LoggerManager getInstance() {
return _instance;
}
public Logger getLogger(String FQCN) {
Logger logger = Logger.getLogger(FQCN);
logger.setLevel(Level.INFO);
return logger;
}
}
i want to change the value of _instance variable using reflection..
basically i want to change the value of the same to _instance = new NewLoggerManager();,
provided that NewLoggerManager extends LoggerManager
is it possible to do so, as i know how to invoke methods, but how to do this one.. ???
Field field = LoggerManager.class.getDeclaredField("_instance");
field.setAccessible(true);
field.set(null, new NewLoggerManager());
the first line obtains the Field definition for the _instance field. Using the "declared" method, because it is able to obtain private fields as well
setting the field to be accessible for reflective operations even if this would not be possible due to its visibility.
setting a new object. Passing null as target object, because the field is static
I have no idea why you need to do this in that way, and basically #Bozho have provided you with correct answer, but I would like to suggest avoiding such traps. You'd better use dependency injection in this case, so it became much more clear and nice and will do the job for you. Try to read about GUICE.

Categories

Resources