Create #Bean for mi method static [duplicate] - java

With this class
#Component
public class Sample {
#Value("${my.name}")
public static String name;
}
If I try Sample.name, it is always 'null'. So I tried this.
public class Sample {
public static String name;
#PostConstruct
public void init(){
name = privateName;
}
#Value("${my.name}")
private String privateName;
public String getPrivateName() {
return privateName;
}
public void setPrivateName(String privateName) {
this.privateName = privateName;
}
}
This code works. Sample.name is set properly. Is this good way or not? If not, is there something more good way? And how to do it?

First of all, public static non-final fields are evil. Spring does not allow injecting to such fields for a reason.
Your workaround is valid, you don't even need getter/setter, private field is enough. On the other hand try this:
#Value("${my.name}")
public void setPrivateName(String privateName) {
Sample.name = privateName;
}
(works with #Autowired/#Resource). But to give you some constructive advice: Create a second class with private field and getter instead of public static field.

Soruce of this info is this: https://www.baeldung.com/spring-inject-static-field
Spring uses dependency injection to populate the specific value when it finds the #Value annotation. However, instead of handing the value to the instance variable, it's handed to the implicit setter instead. This setter then handles the population of our NAME_STATIC value.
#RestController
//or if you want to declare some specific use of the properties file then use
//#Configuration
//#PropertySource({"classpath:application-${youeEnvironment}.properties"})
public class PropertyController {
#Value("${name}")//not necessary
private String name;//not necessary
private static String NAME_STATIC;
#Value("${name}")
public void setNameStatic(String name){
PropertyController.NAME_STATIC = name;
}
}

This is my sample code for load static variable
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class OnelinkConfig {
public static int MODULE_CODE;
public static int DEFAULT_PAGE;
public static int DEFAULT_SIZE;
#Autowired
public void loadOnelinkConfig(#Value("${onelink.config.exception.module.code}") int code,
#Value("${onelink.config.default.page}") int page, #Value("${onelink.config.default.size}") int size) {
MODULE_CODE = code;
DEFAULT_PAGE = page;
DEFAULT_SIZE = size;
}
}

For those who want to use ApplicationContext in the main class of a Spring Boot application, you can just use the return value of SpringApplication.run.

Although workarounds may need to be implemented, one should try to avoid them in most scenarios if possible. Spring is great at handling dependency injection and treats most objects as Singletons. This means that Spring can handle the creation of objects for you, and the injection of these objects at runtime. When combining this with the fact that your Spring managed bean is likely a Singleton, the use of static methods and variables is largely unnecessary. You can simply autowire in an instance of the object you are looking for at the constructor level or variable level and reference the non-static version of the method or variable. This is ideal and behaves similarly to a static reference. Non static variables are basically static because you are only ever using one instance of the object in every part of the code and because of dependency injection you are never handling the instantiation of the object, just like with a static reference! Great! Now I'm sure there are instances where you need the work around (i.e. you aren't using dependency injection or class is not a singleton), but try to not use workarounds if possible. Also this is just my 2 cents. Someone may be able to offer 3. (:
public class InjectableClass{
#Value("${my.value}")
private String myString;
public String nonStaticMethod(){
return myString;
}
}
public class LogicClass{
private InjectableClass injectableClass;
#Autowire
public LogicClass(InjectableClass injectableClass){
this.injectableClass = injectableClass;
}
public void logicClassMethod(){
System.out.println("Hey! Here is the value I set on myString: " +
injectableClass.nonStaticMethod() + ". That was
basically like using a static method!");
}
}

Related

how to inject a dependency in a java enum?

I am trying to inject a bean into an enum but i keep getting null pointer exception when call to someMethod is made.
The answer mentioned in this Inject bean into enum worked for me. I want to know why my code didn't work
#Component
public class DataProvider {
public int method1() {
//somecode
}
}
public enum Genres {
DRAMA(1,”Drama”);
ADVENTURE(2,”Adventure”);
HORROR(3,”Horror”);
private int id;
private String name;
#Inject DataProvider dataprovider;
public int someMethod() {
return dataprovider.method1();
}
}
What the answer you linked does is loop the enum values and use a setter to inject the DataProvider dependency
public void postConstruct() {
for (ReportType rt : EnumSet.allOf(ReportType.class)) {
rt.setDataPrepareService(dataPrepareService);
}
}
It works because the ReportTypeServiceInjector class is an inner, static class, and so it can be seen and instantiated by Spring.
It's a crazy design anyway. Avoid it.
Ultimately, keep the enum simple and extract the DataProvider usage.
Your original code didn't work because Spring cannot #Autowire/#Inject dependencies in enums.
Generally, it is not a good practice to have dependency injection in enums as they are designed to be constants/static (Reference)
But, I agree with you, many times, we need to associate some real time behavior to be encapsulated along with Enum values.
I would suggest, create a new class and encapsulate Enum within that.
class GenresService{
// 1st option: Declare Genres enum reference at class level and
// initialize using class constructor/injection.
// Genres g;
#Inject DataProvider dataprovider;
//2nd option: pass Genres value to method at real time.
public int someMethod(Genres g) {
return dataprovider.method1();
}
}
To have any injection to work you would need to have your enum also managed. You could try to inject your enum but how and what would you inject? It presents constant values and in addition it has private no args constructor.
So the way you might have it working would be some JNDI lookup - that initializes dataProvider - inside your someMethod() or using some static context accessor.
And: for for Spring it is not #Inject but #Resource or #Autowired

Want to call a non-static Interface method in a static method. How?

I facing a real hard problem in my code snippet.
I want to learn how to use Interface in Java the correct way.
So for this I have my Application-Class...
package inversionUsage;
public class Application {
public static void main(String [] args) {
String standard = "Standard version!";
if (FeatureDecisions.checkEnabledFeatures("new-feature1")) {
System.out.println("Implement new feature...");
}else {
System.out.println(standard);
}
}
}
Then I made a Interface...
package inversionUsage;
public interface AppConfiguration {
boolean isEnabled(String searchFeature);
}
I want to use the Interface in another class:
package inversionUsage;
import java.util.Arrays;
public class FeatureDecisions implements AppConfiguration{
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public static boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
if (Arrays.asList(_implNewFeature).contains(searchFeature)) {
return true;
}else {
return false;
}
}
private String [] fetchFeatureTogglesFromSomehere() {
// TODO get the CONFIG from somewhere
enabledFeatures = new String [2];
enabledFeatures[0] = "new-feature1";
enabledFeatures[1] = "new-feature2";
return enabledFeatures;
}
}
So the workflow is:
1. I start the Application
2. Main method checks the enabled features via FeatureDecisions.java
3. In Feature Decisions i implemented the Interface
I getting the error:
Cannot make a static reference to the non-static method isEnabled(String) from the type FeatureDecisions
May Someone can help me out?
The only way to use an instance method is to have an instance on which to call it. Your checkEnabledFeatures is static, so it doesn't receive an instance you can use (as this). To use an instance method, it would need to create an instance. But obviously that's not what you want here.
Java's interface construct is for defining the interface that instances implement. Java doesn't have the concept of a "static interface" that a class must implement. On the rare occasions when that's needed, it's usually implemented using reflection (perhaps with a class-level annotation to indicate that the class has the necessary feature).
You would have to instantiate the FeatureDecisions class.
public static boolean checkEnabledFeatures(String searchFeature) {
return new FeatureDecisions().isEnabled(searchFeature);
}
or make all members static.
Additional info: There are frameworks like togglz that do this for you.
There's no way to do that. The closest can get is to use the singleton pattern (though lots of people - myself included - would discourage it).
public enum FeatureDecisions implements AppConfiguration
{
INSTANCE;
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
//...
}
}
Your call would then change from:
FeatureDecisions.checkEnabledFeatures(...)
to
FeatureDecisions.INSTANCE.checkEnabledFeatures(...)
It's also worth noting that checkEnabledFeatures doesn't actually do anything besides defer to isEnabled. You could scrap the former and just call the latter directly.

How do I access private fields with AspectJ?

I am investigating AspectJ and its many uses and have discovered mixins.
I can find many examples employing pure AspectJ .aj aspects however I need to use only #AspectJ annotations.
What I am trying to achieve is the following:-
I have a class that I cannot amend, it has a private class variable that I need to interrogate after a particular class method has completed execution. This class does not have getter or setter methods associated with this private class variable.
public final class CannotAmend {
private Uri privateUri;
public final void methodOne(){}
public final void methodTwo(){}
public final void methodThree(){
privateUri = "something";
}
}
I require an aspect/mixin that can capture #After methodThree() and allow me to see the value set in privateUri.
Is this possible to achieve?
With #AspectJ annotations?
Where can I discover documentation/tutorial/examples of how to achieve this?
Within an aspect you can access the private field using the reflection API.
In the aspect you need two things:
A pointcut to define methods on which the aspect matches.
And a method annotated with #After containing logic that's executed after a method matched by the pointcut returns.
#Aspect
public class MyAspect {
#Pointcut("execution(* CannotAmend.methodThree(..))")
public void methodThreePointcut(){
}
#After("methodThreePointcut()")
public void afterMethod(JoinPoint joinPoint) throws NoSuchFieldException, IllegalAccessException {
Object instance = joinPoint.getThis();
Field privateUriField = instance.getClass().getDeclaredField("privateUri");
privateUriField.setAccessible(true);
String privateUri = (String) privateUriField.get(instance);
System.out.println(privateUri); // prints "something"
}
}
On a side note, using String constants to access a private field is not a clean solution. If sometime in the future the name of the variable changes or if it's removed, the aspect will break.
Not with mixins, but you can use #Around advice to get JoinPoint and get field through reflection.
For example:
#Around("execution(* *.methodThree())")
public Object getValue(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
System.out.println(pjp.getThis().getClass().getDeclaredField("privateUri").get(pjp.getThis()));
}
}

Guice assisted inject overuse alternatives, dependency injection vs non-DI constructors

The main reasons I like passing in runtime dependencys in constructors are:
It makes the dependency required
It provides a central place to set instance variables
Setting the dependency as an instance variable prevents you from
having to pass it around from method to method within the class or pass it in twice or more
to two or more public methods
This has led me to use a lot of Assisted Injects when using Guice. This creates extra code compared to not using DI so reading things like this:
How exactly is Assisted-inject suppose to be use to be useful?
It seems like most people don't pass the runtime(derived, not available at startup) dependencies in constructors using assisted inject, and instead pass them in individual methods. Thats fine for the simple class given in the above stackoverflow post where there is only one method that relies on the dependency:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(int s) { /* use s */ ... }
}
But what if the class has many methods that use the dependency? Do you pass it from the public method to private methods and require it passed in on all public methods?
For example:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(int s) {
/*some code */
someOtherMethod(s);
anotherMethod(s);
}
//any private method that needs it gets it passed in as a param
private void someOtherMethod(int s)...
private void anotherMethod(int s)...
//require it passed in all public methods that need it
public void anotherPublic(int s){
someOtherMethod(s);
}
}
As opposed to using constructors this adds a bit of extra code as seen here:
public class SomeClass {
private int s;
SomeClass(int s) {
this.s = s;
}
public void doWork() {
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublic(){}
}
Or would you set the instance var from the service method like this?
public class SomeClass {
Integer s;
#Inject
SomeClass(...) {
...
}
public void doWork(Integer s) {
/***set instance var this time***/
this.s = s;
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublicMethod(){
if(s==null){ //check if s was set already
throw new IllegalStateException();
}else{
/* do something else */
}
}
}
Or would you pass the dependency into the other public method as a param and set the instance var there as well? For Example:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(Integer s) {
/***set instance var this time***/
this.s = s;
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublicMethod(Integer s){
this.s = s;
/* do something else */
}
}
So I think passing the param from method to method or throwing illegal state exceptions to check for it isn't ideal compared to using normal constructors, but obviously there are advantages/disadvantages to any framework/pattern.
If I am just not separating my objects in the ideal way, please let me know some guidelines you use, ie "I only use one public method per service class, see this book or post about it:.." .
What do you guys do in the above situations?
You nailed down some great reasons to use assisted injection in your question: It ensures that the object instances only ever exist in a fully-initialized state, keeps your dependencies together, and frees the object's public interface from requiring a predictable parameter in every method.
I don't really have any alternatives to add, other than the ones you mentioned:
Adding a setter method for that dependency, probably requiring IllegalStateException checks or a good default value
Creating an initialize(int s) pseudoconstructor method with the same IllegalStateException checks
Taking in the parameter in individual methods
Replacing the FactoryModuleBuilder boilerplate with a custom factory, thereby creating more extra boilerplate you're trying to avoid
My favorites are the two you seem to be deciding between--assisted injection or taking the parameter in every method--mostly because they both keep the object in a predictable, usable state at all times. My decision between them rests on what kind of state the object should carry, whether that state is mutable, and how I want to control instances. For Car.licensePlateNumber, the license plate number may vary with the car instance; each car has one license plate number that (in this example) never varies, and the car isn't valid without it, so it should be a constructor argument. Conversely, Repository<T> may frequently take in the same T instance in all of its methods, but a Repository is still a Repository no matter which instance you pass in, and you may want the freedom to reuse that instance without creating a new one for each T (as you may have to do with assisted injection). Both designs are valid, and each one is optimal for a certain set of cases.
Remember that there shouldn't really be that much extra code required for assisted injection:
/** In module: install(new FactoryModuleBuilder().build(SomeClass.Factory.class)); */
public class SomeClass {
public interface Factory {
SomeClass create(int s);
}
private final int s;
#Inject
SomeClass(/* ..., */ #Assisted int s) {
this.s = s;
}
public void doWork() { /* ... */ }
}

#value with static field in spring [duplicate]

With this class
#Component
public class Sample {
#Value("${my.name}")
public static String name;
}
If I try Sample.name, it is always 'null'. So I tried this.
public class Sample {
public static String name;
#PostConstruct
public void init(){
name = privateName;
}
#Value("${my.name}")
private String privateName;
public String getPrivateName() {
return privateName;
}
public void setPrivateName(String privateName) {
this.privateName = privateName;
}
}
This code works. Sample.name is set properly. Is this good way or not? If not, is there something more good way? And how to do it?
First of all, public static non-final fields are evil. Spring does not allow injecting to such fields for a reason.
Your workaround is valid, you don't even need getter/setter, private field is enough. On the other hand try this:
#Value("${my.name}")
public void setPrivateName(String privateName) {
Sample.name = privateName;
}
(works with #Autowired/#Resource). But to give you some constructive advice: Create a second class with private field and getter instead of public static field.
Soruce of this info is this: https://www.baeldung.com/spring-inject-static-field
Spring uses dependency injection to populate the specific value when it finds the #Value annotation. However, instead of handing the value to the instance variable, it's handed to the implicit setter instead. This setter then handles the population of our NAME_STATIC value.
#RestController
//or if you want to declare some specific use of the properties file then use
//#Configuration
//#PropertySource({"classpath:application-${youeEnvironment}.properties"})
public class PropertyController {
#Value("${name}")//not necessary
private String name;//not necessary
private static String NAME_STATIC;
#Value("${name}")
public void setNameStatic(String name){
PropertyController.NAME_STATIC = name;
}
}
This is my sample code for load static variable
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class OnelinkConfig {
public static int MODULE_CODE;
public static int DEFAULT_PAGE;
public static int DEFAULT_SIZE;
#Autowired
public void loadOnelinkConfig(#Value("${onelink.config.exception.module.code}") int code,
#Value("${onelink.config.default.page}") int page, #Value("${onelink.config.default.size}") int size) {
MODULE_CODE = code;
DEFAULT_PAGE = page;
DEFAULT_SIZE = size;
}
}
For those who want to use ApplicationContext in the main class of a Spring Boot application, you can just use the return value of SpringApplication.run.
Although workarounds may need to be implemented, one should try to avoid them in most scenarios if possible. Spring is great at handling dependency injection and treats most objects as Singletons. This means that Spring can handle the creation of objects for you, and the injection of these objects at runtime. When combining this with the fact that your Spring managed bean is likely a Singleton, the use of static methods and variables is largely unnecessary. You can simply autowire in an instance of the object you are looking for at the constructor level or variable level and reference the non-static version of the method or variable. This is ideal and behaves similarly to a static reference. Non static variables are basically static because you are only ever using one instance of the object in every part of the code and because of dependency injection you are never handling the instantiation of the object, just like with a static reference! Great! Now I'm sure there are instances where you need the work around (i.e. you aren't using dependency injection or class is not a singleton), but try to not use workarounds if possible. Also this is just my 2 cents. Someone may be able to offer 3. (:
public class InjectableClass{
#Value("${my.value}")
private String myString;
public String nonStaticMethod(){
return myString;
}
}
public class LogicClass{
private InjectableClass injectableClass;
#Autowire
public LogicClass(InjectableClass injectableClass){
this.injectableClass = injectableClass;
}
public void logicClassMethod(){
System.out.println("Hey! Here is the value I set on myString: " +
injectableClass.nonStaticMethod() + ". That was
basically like using a static method!");
}
}

Categories