Spring Boot application.properties appear unregistered when accessed from constructor - spring

This is the code that I have:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
public Program() {
System.out.println(appTitle);
}
}
The application.properties has
app.title=The Program
The output is null insteaf of The Program.
So, what am I missing? I have tried several examples; none worked.

Since appTitle is an autowired field, it is not set until after the object is initially constructed. This is why the value is still null in your example. The bean construction process in this scenario is as follows:
The Program constructor is called, creating a new Program instance
The appTitle field is set on the newly constructed bean to ${app.title}
The ideal fix for this depends on your goals. If you truly need the value within the constructor, you can pass it in as an autowired constructor parameter. The value will then be available within the constructor:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
public Program(#Value("${app.title}") appTitle) {
System.out.println(appTitle);
}
}
If you don't need it in the constructor itself, but need it for the proper initialization of the bean, you could alternatively use the #javax.annotation.PostConstruct annotation to make use of it after the object's construction but before it is made available for use elsewhere:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
#PostConstruct
public void printAppTitle() {
System.out.println(appTitle);
}
}
Finally, if you don't need the value at construction time, but need it during the life of the bean, what you have will work; it just won't be available within the body of the constructor itself:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
}

Nothing wrong, just don't do it in a constructor...

Other answers on this question are written assuming the goal is creating a Spring-managed bean that uses the given property in its creation. However, based on your comments in another answer, it looks like the question you want answered is how to access an externalized property (one provided by #Value) within a no-argument constructor. This is based on your expectation that a Java inversion of control (IoC) container such as Spring should allow accessing externalized properties (and presumably other dependencies) within a no-argument constructor. That being the case, this answer will address the specific question of accessing the property within a no-argument constructor.
While there are certainly ways this goal could be achieved, none of them would be idiomatic usage of the Spring framework. As you discovered, autowired fields (i.e. fields initialized using setter injection) cannot be accessed within the constructor.
There are two parts to explaining why this is. First, why does it work the way it does, programmatically? Second, why was it designed the way it was?
The setter-based dependency injection section of the Spring docs addresses the first question:
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.
In this case, it means that first the object is created using the no-argument constructor. Second, once the object is constructed, the appTitle is initialized on the constructed bean. Since the field isn't initialized until after the object is constructed, it will have its default value of null within the constructor.
The second question is why Spring is designed this way, rather than somehow having access to the property within the constructor. The constructor-based or setter-based DI? sidebar within the Spring documentation makes it clear that constructor arguments are in fact the idiomatic approach when dealing with mandatory dependencies in general.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. [...]
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. [...]
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. [...]
A property needed to construct the object certainly would be categorized as a mandatory dependency. Therefore, idiomatic Spring usage would be to pass in this required value in the constructor.
So in summary, trying to access an application property within a no-argument constructor is not supported by the Spring framework, and in fact runs contrary to the recommended use of the framework.

Related

Kotlin instance variable is null when accessed by Spring proxied class

I have a service class that is being proxied by Spring, like so:
#Service
#Transactional
open class MyService { ... }
If I remove the open modifier, Spring complains that it needs to proxy the class to apply the #Transactional annotation tweaks.
However, this is causing issues when calling a function on the proxied service, which attempts to access a variable:
#Service
#Transactional
open class MyService {
protected val internalVariable = ...
fun doWork() {
internalVariable.execute() // NullPointerException
}
}
The internalVariable is assigned as part of its declaration, does not have any annotations (like #Autowired, etc.), and works fine when I remove the #Transactional annotation and the requirement for Spring to proxy the class.
Why is this variable null when Spring is proxying/subclassing my service class?
I hit a similar issue and the above comments by Rafal G & Craig Otis helped me-- so I'd like to propose that the following write up be accepted as an answer (or the comments above be changed to an answer and they be accepted).
The solution: open the method/field.
(I hit a similar case where it was a closed method that caused the problem. But whether it is a field/method the solution is the same, and I think the general cause is the same...)
Explanation:
Why this is the solution is more complicated and definitely has to do with Spring AOP, final fields/methods, CGLIB proxies, and how Spring+CGLIB attempts to deal with final methods (or fields).
Spring uses proxies to represent certain objects to handle certain concerns dealt with by Aspect Oriented Programming. This happens with services & controllers (especially when #Transactional or other advice is given that requires AOP solutions).
So a Proxy/Wrapper is needed with these beans, and Spring has 2 choices-- but only CGLIB is available when the parent class is not an interface.
When using CGLIB to proxy classes Spring will create a subclass called
something like myService$EnhancerByCGLIB. This enhanced class will
override some if not all of your business methods to apply
cross-cutting concerns around your actual code.
Here comes the real surprise. This extra subclass does not call super
methods of the base class. Instead it creates second instance of
myService and delegates to it. This means you have two objects now:
your real object and CGLIB enhanced object pointing to (wrapping) it.
From: spring singleton bean fields are not populated
Referenced By: Spring AOP CGLIB proxy's field is null
In Kotlin, classes & methods are final unless explicitly opened.
The magic of how Spring/CGLib when & how chooses to wrap a Bean in an EnhancerByCGLIB with a target delegate (so that it can use finalized methods/fields) I don't know. For my case, however the debugger showed me the 2 different structures. When the parent methods are open, it does not create a delegate (using subclassing instead) and works without NPE. However, when a particular methods is closed then for that closed method Spring/CGLIB uses a wrapped object with delegation to a properly initialized target delegate. For some reason, the actual invocation of the method is done with the context being the wrapper with its uninitialized field values (NULLs), causing NPE. (Had the method on the actual target/delegate been called, there should not have been a problem).
Craig was able to solve the problem by opening the property (not the method)-- which I suspect had a similar effect of allowing Spring/CGLib to either not use a delegate, or to somehow use the delegate correctly.

Methods of Autowiring in Spring - Difference between the two possible alternatives below

I have a basic Auto-wiring Question. I see the following two implementations that are possible in Spring auto-wiring
Method1
public class SimpleMovieLister {
private MovieFinder movieFinder;
#Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
Method2
public class SimpleMovieLister {
#Autowired
private MovieFinder movieFinder;
}
My understanding is that both are the same and I use a lot of Method2 in my code. What are the situations in which Method1 is useful ? Or is it just a case of Spring evolution and we have both possible ways in which to implement.
Sorry, if the question is too basic, but I need to get this cleared up
Method 1 is Setter Injection.
Method 2 is Field Injection.
A 3rd method is Constructor Injection
Example:
public class SimpleMovieLister {
private MovieFinder movieFinder;
#Autowired
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
Method 3, Constructor Injection is preferred because it makes testing significantly easier since you can pass in the required dependency.
Also, if your Bean only has 1 Constructor, then you can omit the #Autowired annotation. Spring will automatically choose that constructor method when creating the bean.
A good snippet from the docs:
The Spring team generally advocates constructor injection as it
enables one to implement application components as immutable objects
and to ensure that required dependencies are not null. Furthermore
constructor-injected components are always returned to client
(calling) code in a fully initialized state. As a side note, a large
number of constructor arguments is a bad code smell, implying that the
class likely has too many responsibilities and should be refactored to
better address proper separation of concerns.
Setter injection should primarily only be used for optional
dependencies that can be assigned reasonable default values within the
class. Otherwise, not-null checks must be performed everywhere the
code uses the dependency. One benefit of setter injection is that
setter methods make objects of that class amenable to reconfiguration
or re-injection later. Management through JMX MBeans is therefore a
compelling use case for setter injection.
Use the DI style that makes the most sense for a particular class.
Sometimes, when dealing with third-party classes for which you do not
have the source, the choice is made for you. For example, if a
third-party class does not expose any setter methods, then constructor
injection may be the only available form of DI.
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html
Method 1 is setter Injection
Setter injection should primarily only be used for optional
dependencies that can be assigned reasonable default values within the
class. Otherwise, not-null checks must be performed everywhere the
code uses the dependency. One benefit of setter injection is that
setter methods make objects of that class amenable to reconfiguration
or re-injection later.
Method 2 is field Injection

how spring singleton scope for DAO class works internally

I went through some blogs and spring docs about the Spring singleton scope along with almost all spring singleton and DAO related question in stackoverflow.
I still do not have clear understanding of how the same object is injected to all the class which depend on it. I have learnt that the DAO needs to be stateless.
If the following DAO (sample dao having instance variable mainly to clear confusion) class is defined with default singleton scope and the same object is injected everytime, then there might be scenarios where department is null and therefore it won't set anything for department value instead use whatever the previous object value was.
public class UserDAO{
int userId;
Spring userDepartment;
// getter setter methods for userId and userDepartment
public boolean addUserToUserDetailsTable(int uId,
String name, String address, String department){
// set userId
userId = uId;
if(department!=null)
userDepartment = department;
// write code to add user to user table
// TO DO
// save user department data
addUserToUserDepartmentTable(userId, userDepartment);
}
public void addUserToUserDepartmentTable(int uId,
String department){
/* Code to save department data */
}
}
So if instead of using DI, if I manually call the DAO using new operator this problem won't be there.
new UserDAO().addUserToUserDetailsTable(id, "abc", null);
the above confusion generates following questions
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes. If this is true then how the previous object values from above DAO class is reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ?? Does stateless means the class cannot have instance variable.
does spring internally uses new object() to inject the beans.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
Please help me clearing the above confusion.
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes.
Yes, it's injecting a single instance, always the same, of the DAO class. That's the definition of singleton: a single instance is created.
If this is true then how the previous object values from above DAO class is reset.
It's not reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ??
Yes, the unique instance will hold the userId and department, since these are fields of the instance. You might run into problems trying to read and write these values, though, since they constitute shared mutable state, which is accessed concurrently from multiple threads without any synchronization.
Does stateless means the class cannot have instance variable.
In the strict sense, yes. But a DAO doesn't need to be stateless. It needs to be thread-safe, since the same instance is accessed from multiple threads concurrently. The best way to achieve that is to avoid having any state (so no instance variable). But this is hard to achieve for a DAO, which normally needs to have access to an injected DataSource, of JdbcTemplate, or EntityManager, or whatever. Since, however, these instance variables are normally injected by Spring during startup, before the DAO starts being used by multiple threads, and never written to during the lifetime of the application, that is thread-safe. Your code, however, has state, and the state is modified during the lifetime of the application, which makes it not safe.
does spring internally uses new object() to inject the beans.
It depends how the DAO bean is declared. It can be declared using JavaConfig, using a #Bean method calling the constructor. Most of the time, reflection is used to call the constructor. So there is no new MyDAO() in the code anywhere, but the constructor is still called (only once since it's a singleton), because that's the only way to create an instance of an object from scratch.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
That wouldn't be a singleton if it did that.
Singleton scope beans in Spring means one instance per container and the bean has to be stateless or else you will run into issues in cases of multi-threaded scenarios.
how is spring creating and injecting singelton beans, is it really
one and only one object which gets injected to all calling classes.
Spring creates once instance at startup and passes the same reference to all the calling objects which has requested for the same via Dependency injection.
If this is true then how the previous object values from above DAO
class is reset.
If your bean is stateless there would be no value held by the object, as most of the variable would be method local and not tied to the Instance object (DAO class in this case). However in your case since you have member variable tied to a class
all the classes which acquire this DAO bean would see the same value set to the member variable and this data will be be corrupted and is not recommended.
won't the instance variable hold their values here userId,
userDepartment if the same object is called from multiple class ??
Does stateless means the class cannot have instance variable.
Yes this the exact definition of bean being stateless. As explained above.
does spring internally uses new object() to inject the beans. or it
creates an object of DAO class and makes multiple clones of the
object, which i think is not possible because the DAO class is not
implementing clonnable.
If you have not defined the bean scope, by default spring would assume it is Singleton. The understanding of singleton scope and singleton pattern is different. Spring mimics singleton pattern by providing only instance but this does not stop you from creating new instance (using say new operator).
Your Singleton is not stateless. Userid and Department define the 'state'.
Spring creates one instance using reflection 'newInstance' or a producer function in your configuration.
This one instance is then provided to all objects requesting the DAO.
Your considerations are all valid but not resolved by spring: Since your DAO has a state, it is not properly implemented and results are undefined.
Answer to question 1: It is not reset. Spring won't handle state for you!
Basically (Q2) you are on a dangerous path if you use instance variables in stateless beans. The instance vars need to be stateless themselves, like other DAO singletons.
UPDATE: I want to elaborate on this. The singleton can have a state, but the state is shared between all users of the DAO. This does not strictly require your DAO to be thread safe: If you do not use threads, there is no concurrent use - but the state of a singleton is a shared state: All users of the singleton have the same. If you have two functions like so:
#Component
public class A {
#Autowired
DaoObject singleton;
#Autowired
B another;
public void aFunctionA() {
singleton.userId = "Foo";
System.out.printf("UserId: %s%n", singleton.userId); // prints Foo
another.aFunctionB();
System.out.printf("UserId: %s%n", singleton.userId); // prints Serviceuser
}
}
#Service
public class B {
#Autowired
DaoObject singleton;
public void aFunctionB() {
singleton.userId = "Serviceuser";
}
}
The state of the singleton singleton is shared between all users of the class. If one class changes the state, all other users have to cope with that.
If you are using threads, this adds extra complexity on stateful singletons, as your modifications to state must be thread safe.
It is common practice to keep a singleton immutable after initialization.
On your 4th question: Spring will not clone a Singleton, as described above.

Faker for Grails gives variable not defined error

I have a Grails 2.4.4 application configured with spring-security-core. I want to generate fake users in the BootStrap using the faker plugin. However when I instantiate the bean fakerService in BootStrap and try using it ie. fakerService.firstname(), I get an error :
ERROR context.GrailsContextLoaderListener - Error initializing the application: Cannot invoke method firstName() on null object
Message: Cannot invoke method firstName() on null object
I'm just a beginner in Grails. Am I doing the Dependency Injection wrong?
http://pasteboard.co/rvbihRU.png
Yes you are :)
A little background. When you add a class-scope variable (a field) in a Groovy class without an explicit scope modifier (e.g. public, private, protected) it defaults to public just like classes and methods. But it is considered a property in the JavaBean sense, so the Groovy compiler creates a getter and a setter for you based on the name. So if you declare def foo and String bar (it doesn't matter whether you specify the type) you'll get Object getFoo(), void setFoo(Object), String getBar(), and void setBar(String) methods (you should decompile a POGO class with a decompiler and see this for yourself - it's pretty cool stuff - I recommend JD-GUI, but use whatever you prefer). If you had declared any of them already Groovy would skip that one and not overwrite yours. This is cool because you can treat the variable like a simple public field, but at any time add getter and/or setter logic and not affect calling clients (Groovy or Java, since the Java classes would have been calling the getter and setter all along, and Groovy calls the getter and setter for you when you read or write a property).
So why am I babbling on about this? Dependency injection is done by Spring - you're injecting Spring beans. There are various ways to do this, but the default in Grails is to use autoinject-by-name. So for any bean registered in the ApplicationContext and special classes like BootStrap, integration tests, etc., Spring scans the methods looking for setters. It strips off "set" and lowercases the next letter, and that's the "property" name of the setter. If there's a bean with that name in the ApplicationContext, Spring will call that setter, passing the bean with that name, and if the types are in sync, your class will have a reference to that bean.
You added a local variable. Nothing special happens to local variables, and Spring doesn't see them, and they're not candidates for dependency injection. Move the declaration to class scope, before the init closure, e.g.
class BootStrap {
def fakerService
def init = {
...
}
}
and the Groovy compiler will add a getFakerService method that isn't of much interest, but also a setFakerService method that Spring will see. It will determine that its property name is "fakerService", see that there is a bean with that name, and call the setter. This all happens before Grails calls the init closure, so at that point the value will be a non-null FakerService eagerly awaiting your calls.

What does the #Value annotation in method do?

I see one method annotated with #Value("${some.property}")
as in
#Value("${some.property}")
public void setSomething(String param) {
... do something with param
}
What is that annotation doing there?
Basically it tells Spring's AutowiredAnnotationBeanPostProcessor to call the setSomething method with the resolved value of some.property as the argument... but only if you have a PropertySourcesPlaceholderConfigurer in your bean definitions; if you haven't configured one the post processor will only inject the string "${some.property}"(without quotes) to your method.
An IllegalArgumentException will be thrown if the value could not be resolved unless you have used a default e.g. "${some.property:default}".
Spring resolves these values using the current Environment and its PropertySources e.g. JVM system properties, a Java properties file, etc.
Also you may use Spring Expression Language (SpEL) to resolve things like #{someBean.someMethod} or #{systemProperties[user.region]}
Sidenote: As the documentation states
Fields are injected right after construction of a bean, before any
config methods are invoked. [...] Bean property setter methods [as in this case] are effectively just a special case of such a general config method.
A common mistake is to try to execute some logic in your constructor using the value injected but at this moment the value has not be resolved nor injected because the constructor must finish in order to inject the value in the config method. In these cases you have to use the #Value or #Autowired annotations in your constructor arguments.
You may also use #PostConstruct or the XML init-method attribute pointing to a method that will be executed after the bean properties have been set. Alternatively you can implement the InitializingBean interface.

Resources