How to Inject a managed bean(non-static) into static method? - java

I am using Java CDI for bean lifecycle.
#Named
public class ManagedBeanClass{
...
public ManagedProfile getManagedProfile(){
return new ManagedProfile();//logic will goes here
}
}
For Example
public class sample1{
#Inject private ManagedBeanClass managedBeanClass;
...
public static boolean methodExample() throws Exception{
ManagedProfile managedProfile = managedBeanClass.getManagedProfile();
....
}
}
Try to Inject(#Inject) Managed bean into Static method ,it shows compaliaton error
Cannot make a static reference to the non-static field
managedBeanClass
Getting stuck with Context DI and Static Object lifecycle.
Help me resolve this thanks in advance.

The problem in your example code has nothing to do with CDI; You are trying to access a non-static field (managedBeanClass) from a static method. This is not possible in Java (neither with nor without CDI).
Also, static methods almost always point to a design problem (*). Having static methods like that make your program harder to test and harder to change / maintain. Try to come up with a design that does not need static methods at all...
So, the short answer is: Don't.
But if your really must have a static method here, you can use constructor injection and set a static field from the constructor. But beware: This is potentially dangerous, because every new instance would set the field again (which could cause race conditions and unexpected behaviour).
(See also: https://stackoverflow.com/a/22068572/10363398)
(*) With a few exceptions, like the methods in the Math class. But those are very small, pure functions that have no side-effects.

Related

Why enum singleton is lazy?

I saw answers like these, tried to clarify via comments, and was unsatisfied by examples here.
Maybe it's time for this specific question...
Why enum singleton implementation is called lazy?
public enum EnumLazySingleton {
INSTANCE;
EnumLazySingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
How it is different from eager implementation?
public class BasicEagerSingleton {
private static final BasicEagerSingleton instance = new BasicEagerSingleton();
public static BasicEagerSingleton getInstance() {
return instance;
}
private BasicEagerSingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
Both will init instance without accessing INSTANCE/getInstance() - e.g. call touchClass().
public class TestSingleton {
public static void main(String... args) {
System.out.println("sleeping for 5 sec...");
System.out.println("touching " + BasicEagerSingleton.class.getSimpleName());
BasicEagerSingleton.touchClass();
System.out.println("touching " + EnumLazySingleton.class.getSimpleName());
EnumLazySingleton.touchClass();
}
}
Output:
sleeping for 5 sec...
touching BasicEagerSingleton
constructing: BasicEagerSingleton#7bfcd12c
touching EnumLazySingleton
constructing: INSTANCE
Now, we can say both are lazy. What is eager then?
It is clear how (e.g) "double-checked locking" way is actually lazy (and messy, and slow). But if enum is lazy, then any singleton is lazy due to inevitable class loading - in fact, everything is lazy. At which point will this distinction stop making any sense?
The first two linked answers (by Peter Lawrey and Joachim Sauer) both agree that enums are not lazily initialized. Answers in the third link are simply wrong about what lazy initialization means.
The recommendation to use enums as singletons originates from Josh Bloch's Effective Java. Notably, the chapter on enum singletons makes no mention of laziness. There is a later chapter dedicated to lazy initialization, that likewise makes no mention of enums. The chapter contains two highlights.
If you need to use lazy initialization for performance on a static field, use the lazy initialization holder class idiom.
If you need to use lazy initialization for performance on an instance field, use the double-check idiom.
Undoubtedly, enums would be another idiom on this list if they were in any way lazily initialized. In fact they are not, although confusion about the meaning of lazy initialization results in some incorrect answers, as the OP shows.
May I wager the following:
You are trying to identify 2 "processes" or ... "things" (let's make this easy to understand - because if I start saying "Code Blocks", it sounds more difficult)...
At some point the class-loader will run, and you would like to know what "things" will be executed when the class-loader loads a class.
At another point invoking a method on the class will cause another "thing" to run / execute, and you would like to know which, exactly, (which "processes") would start..
The following facts are relevant:
Static initializers are run when the class-loader loads the class. The class-loader will not load the class until the code that is
running encounters the need to load it (because a method or field has
been invoked) such as: touchClass()
If a singleton instance of EITHER a class, OR an enumerated type has a field that is being initialized in the static
part of the class it will be loaded as soon as you 'touch' the
class - because the Class-Loader runs all static initializations for a class or enum on loading.
Lazy loading, likely, (And this is my "interpretation" about what you are asking) would happen when a method invokation asks the class
to create a singleton instance - which could happen quite a bit of
time after the "loading" of the class or enum.
A class like the following:
public class LazySingleton
{
// At time of class-loading, this singleton is set to 'null'
private static singleton = null;
// This is a method that will not be invoked until it is called by
// some other code-block (some other "thing")... When "touchClass()"
// is called, the singleton instance is not created.
public static LazySingleton retrieveSingleton()
{
if (singleton == null) singleton = new LazySingleton();
return singleton;
}
// DOES NOTHING... The Singleton is *not* loaded, even though the
// Class Loader has already loaded this Java ".class" file
// into memory.
public static void touchClass() { }
private LazySingleton()
{ System.out.println("constructing: LazySingleton"); }
}
Here on the other hand:
public enum EagerEnum
{
// The class loader will run this constructor as soon as this 'enum'
// is loaded from a '.class' file (in JAR or on disk) into memory
MyEnumConstant();
private EagerEnum()
{ System.out.println("Eager Enum Constructed"); }
// This will cause the Class Loader to Load this enum from the
// Java ".class" File immediately, and the "MyEnumConstant" will
// also have to be loaded - meaning the constructor will be called.
public static void touchEnum() { }
}
So the following code would produce the output
LazySingleton.touchClass(); // Prints nothing
EagerEnum.touchClass(); // Prints "Eager Enum Constructed"
LazySingleton.getSingletonInstance(); // Prints "constructing: LazySingleton

Use dynamic class name in private static final variable of a class

Consider and example as below:
public class LoggerTestClass {
private static final Logger LOGGER = Logger.getLogger(LoggerTestClass.class);
}
In above example parameter passed to getLogger method is hard coded i.e LoggerTestClass.class
Now every time I change the class name I have to change the getLogger method's parameter.
Any other way which will fetch the class name automatically, for example for non static variable we can add this.getClass()
You can use Lombok to achive it in a clean fashion. All you need to do is to put #Log on top of your class and it will give you a log object to work with.
Read more here
Bro,For the question,first of all,we need make clear some concept.
In java,if a identifier is a member of a class,and decorated by 'static' keyword,it's value is Decided in the compile phase.
If the 'final' keyword is added,the identifier is constant,it's value must have a initial value on it is declared.and the value can't be change in the java runtime.
And the interesting thing is, the static constent is only declared inside the class,it can be called 'Classname' + '.' ,but has no connection to the class context.if there's no context ,the identifier con't become dynamic.
I think if let the identifier become dynamic ,there are only two ways:
let the identifier become a variable.remove the 'final' key word.the code look like this:
class Test {
private static Logger LOGGER;
public Test() {
LOGGER = Logger.getLogger(getClass().getSimpleName());
}
}
The 'private' keyword is sufficient if you don't want other classes to access it.
Try the java dynamic proxy. it can change the class in java runtime.
Code happy ~
Welcome to talk with me~
Can you use java 9+? Then solution is pretty simple:
private static final Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass());
As MethodHandles.lookup() creates lookup using caller class. (via Reflection.getCallerClass() but Reflection is internal API, so you need that additional method handle lookup step)

How to use guice injection for an existing singleton class?

I have an existing class named Legacy which is mostly written in old school singleton pattern. Now I want to introduce a new field to it and I would like to use Guice. Legacy itself is not Guice controlled, it is used by another Service class (inside the Service class, it calls the getInstance() of Legacy class to retrieve the Legacy object right now), and that Service class is been created using Guice injector.
public class Legacy {
public synchronized static Legacy getInstance() {
if(sInstance == null) {
sInstance = new Legacy();
}
return sInstance;
}
private Legacy() {
legacyObj = LegacyField.getInstance(); // get a singleton
}
private static Legacy sInstance;
private LegacyField legacyObj;
private NewField newObj; // this is the new dependency I would like to add using Guice
}
What I tried is that I tried to put method Inject into Legacy class
#Inject
public void setNewField(NewField newObj) {
this.newObj = newObj;
}
And in the module file of the Service, I bind the NewField object, but when I run the program, it throwed a NullPointer exception. So the inject doesn't work. Any idea of how to make NewField inject into my program but keep the current old-school singleton paradigm and not changing too much about everything else?
EDIT
There are a least three solutions below and I don't quite know which is the best or are they equivalent.
I just found another solution:
// put in the module
bind(Legacy.class).toInstance(Legacy.getInstance());
In this example, your module itself, not Guice, takes responsibility for obtaining a Legacy instance, then asks Guice to always use this single instance to fulfill all Legacy injection requests.
But according to the javadoc
When the Injector is created, it will automatically perform field and method injection for this instance, but any injectable constructor on Legacy is simply ignored. Note that using this approach results in "eager loading" behavior that you can't control.
Though only slightly cleaner than Thomas's answer, you can configure the injection of your Singleton from within your Module using requestInjection or requestStaticInjection.
// In your Module:
requestInjection(Legacy.getInstance()); // for an instance field, or
requestStaticInjection(Legacy.class); // for a static field.
The docs on the wiki warn about the downsides, though:
This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.
Here is a somewhat hackish solution.
In the bootstrapping of your application,
may be in method public static void main(String[] args),
you should already have code similar to this:
Injector injector = Guice.createInjector(yourModule);
At this place add the following line:
injector.injectMembers(Legacy.getInstance());
By doing so, all the #Injects in your Legacy singleton
should be resolved.
See also the javadoc of Injector.injectMembers.

How to deal with special "constant" instances of object when using DI

My project is heavily using dependency injection, and I'm being very careful to avoid service locator antipattern. All objects are structured using constructor injection that allow easily identifiable list of dependencies. Now I'm building an object, and it has a special "constant" instance, which is basically static/singleton (consider example of something like Integer.MinValue). So my initial reflex was to create a static field with a static "getter" method, which would create the instance of the object if it wasn't previously created. The object itself has dependencies however, so I'm confused on what's the best practice for instantiating this "special instance". I'm looking for recommendations on how to best structure code in this scenario, ideally without having to call upon the container for resolution of dependencies. Some code:
public class PressureUnit extends DataUnit {
private static PressureUnit standardAtmosphere;
public static PressureUnit StandardAtmosphere() {
if(standardAtmosphere == null){
standardAtmosphere = new PressureUnit(1013.25); // this line is what is bothering me as I need to resolve other dependencies (have to use new as it's a static method and can't be injected like everywhere else)
}
return standardAtmosphere;
}
#AssistedInject
public PressureUnit(ITimeProvider timeProvider, IUnitProvider unitProvider, #Assisted double value) {
this(timeProvider, unitProvider, value, PressureUnits.hPa);
}
...
}
I really don't see any problem in your code since you are not newing up dependencies here and there, now with that being said i can give some suggestions:
If you specifically want the container to call an existing static factory method, you can use StaticFactoryExtension.
Why don't you use a factory.
Consider refactoring you design and removing the static method if possible.

Control class loading order in Java

I've created a class which holds a bunch of properties values.
In order to initialize that class, I have to call some static method "configure()" which configures it from an XML file.
That class was supposed to act to store some data such that I could just write
PropClass.GetMyProperty();
I call the configure() from a static block in the main so I can use it anywhere
BUT
If I set a static constant member of some other class to a value from my "PropClass", I get null,
class SomeClass {
static int myProp = PropClass.GetMyProperty();
}
That's probably because that expression is evaluated before the call to configure.
How can I solve this issue?
How can I enforce that the call to configure() will be executed first?
Thanks
you could use a static code block to do that
static {
configure();
}
the syntax of a static initializer block? All that is left is the keyword static and a pair of matching curly braces containing the code that is to be executed when the class is loaded. taken from here
I would do the following:
class SomeClass
{
// assumes myProp is assigned once, otherwise don't make it final
private final static int myProp;
static
{
// this is better if you ever need to deal with exceeption handling,
// you cannot put try/catch around a field declaration
myProp = PropClass.GetMyProperty();
}
}
then in PropClass do the same thing:
class PropClass
{
// again final if the field is assigned only once.
private static final int prop;
// this is the code that was inside configure.
static
{
myProp = 42;
}
public static int getMyProperty();
}
Also. if possible, don't make everything static - at the very least use a singleton.
Can you not make the GetMyProperty() method check whether configure() has been called already ? That way you can call GetMyProperty() without having to worry about wheher our object is configured. Your object will look after this for you.
e.g.
public String getMyProperty() {
if (!configured) {
configure();
}
// normal GetMyProperty() behaviour follows
}
(you should synchronise the above if you want to be thread-safe)
Dude, sounds like you should be using Spring Framework (or some other Dependency Injection framework). In Spring, you already get everything that you need:
An XML format for defining beans with configurable properties, no need to code the logic for reading the XML and initializing the beans yourself.
Beans are initialized when you need them (provided that you access them in the correct manner). The best way would be to inject the beans into the callers.
Don't invent the wheel... Spring is one of the most commonly used frameworks in Java. IMHO, no large Java application should be coded without it.

Categories

Resources