guice injection in static variable - java

I Have doubt about guice injection.
Is it possible to inject a #named variable value to a static variable?
I have tried
#Provides
#Named("emp.id")
public Integer getEmpId() {
return 2;
}
and tried to inject this value to static variable such as
#Inject
#Named("emp.id")
private static Integer id;
But the id return value null, When I removed static modifier the id gave value 1.
What is really happening here?

Guice does not inject static fields by design. You can request static injection but this should be done only as a crutch:
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.
In your case you could add this to your configure method to have your static field injected by Guice:
requestStaticInjection(Foo.class);
If you don't add this the Integer will be initialized to null (by default).
I have no idea why id was set to 1 after you removed the static modifier, however. Seems that it should have been set to 2 if your Guice module was setup correctly.

Related

Internal working of field injection in spring and why is it not recommended to use

As the title suggests , I want to know how does field injection internally works in spring , I read many articles on this and got to know few things like below but didn't understood the exact reason behind it :
-> It should not be used because when you do unit testing then you are dependent upon the spring
container to instantiate the class in case of field injection.
-> You cannot use "final" keyword in case of field injection , means you cannot make the field immutable.
-> It internally uses reflection
I want to know how exactly does #Autowired works internally , how does it uses reflection , I am trying to understand the exact reason behind all the above mentioned points, what happens behind the scenes when we write the below code :
#Component
public class B {
#Autowired
private A a1;
}
I have read similar questions on stack overflow about this topic , but I couldn't find the exact explanation that I am looking.
Spring has a concept of Bean Post Processors.
When spring builds a bean it applies registered bean post processors that help to "initialize" the bean.
So, there is org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor that handles autowiring.
Basically it works with an newly created object. Spring introspects the fields of the beans (by using reflection). The fields that have #Autowired is a subject for processing with this bean post processor. It finds the candidate for injection in the application context and actually injects the value.
Now given this information, its understandable why final fields cannot be autowired. Leave alone spring, In pure Java, final fields must be instantiated directly right during the declaration (final int i = 123) or in the constructor of the class. But the autowiring happens after constructor, so its impossible to autowire the final fields.
As for the unit testing, the private properties must be somehow configured from the test. But since they're encapsulated (yes, spring kind of breaks encapsulation in this case for its usage), its impossible to write a good test for the class that contains fields injection. That's is a reason to switch to constructor injection.
public class FieldInjection {
#Autowired
private A a;
}
VS.
public class ConstructorInjection {
private final A a;
// this can be generated by lombok, you don't have to put #Autowired on constructor in the case of single constructor, spring will use it to create a bean
public ConstructorInjection(A a) {
this.a = a;
}
}
Now the test for FieldInjection class is impossible:
public class FieldInjectionTest {
#Test
void test() {
FieldInjection underTest = new FieldInjection();
how do you know that you should instantiate A a. ????
}
}
However in the case of constructor injection its a trivial task:
public class ConstructorInjectionTest {
#Test
void test() {
A a = mock(A.class);
ConstructorInjection underTest = new ConstructorInjection(a);
// the dependencies must be supplied in the constructor
// otherwise its impossible to create an object under test
}
}

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

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.

Spring #Autowired and #Value on property not working

I would like to use #Value on a property but I always get 0(on int).
But on a constructor parameter it works.
Example:
#Component
public class FtpServer {
#Value("${ftp.port}")
private int port;
public FtpServer(#Value("${ftp.port}") int port) {
System.out.println(port); // 21, loaded from the application.properties.
System.out.println(this.port); // 0???
}
}
The object is spring managed, else the constructor parameter wouldn't work.
Does anyone know what causes this weird behaviour?
Field injection is done after objects are constructed since obviously the container cannot set a property of something which doesn't exist. The field will be always unset in the constructor.
If you want to print the injected value (or do some real initialization :)), you can use a method annotated with #PostConstruct, which will be executed after the injection process.
#Component
public class FtpServer {
#Value("${ftp.port}")
private int port;
#PostConstruct
public void init() {
System.out.println(this.port);
}
}
I think the problem is caused because Spring's order of execution:
Firstly, Spring calls the constructor to create an instance, something like:
FtpServer ftpServer=new FtpServer(<value>);
after that, by reflection, the attribute is filled:
code equivalent to ftpServer.setPort(<value>)
So during the constructor execution the attribute is still 0 because that's the default value of an int.
This is a member injection:
#Value("${ftp.port}")
private int port;
Which spring does after instantiating the bean from its constructor. So at the time spring is instantiating the bean from the class, spring has not injected the value, thats why you are getting the default int value 0.
Make sure to call the variable after the constructor have been called by spring, in case you want to stick with member injection.

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