I have a class A which contains a property
class A{
String valA;
}
I have two classes B and C which have a reference to class A
class B{
#Autowired
private A aaa;
}
class C{
#Autowired
private A aaa;
}
The valA in class A would be property driven and should depend on which class in actually invoking it.
If class B is invoking it , it should be some thing like b.property defined in a property file
and for class C the value would be c.property
Is this possible to do this without using an XML configuration and only annotation , SPEL etc
Thanks in Advance
You need two different instances of A (one for B and one for C), because you can not change the value of an property in A depended on the way A is invoked*.
Have a look at the concept of qualifies to see how they can be used to distinguishes between two instances of the same class.
footenote * of course you can change the parameter in A depended on how A is invoked, but this requires a lot of technical code and some hacks. And should be not the code you want to have in your spring app.
Related
So, I have created configuration class with #Component and #ConfigurationProperties(prefix = "properties"), set default values for some of my application properties and changed some of them in application.yaml/properties
Now, I know I can access it using #Value("properties.*") but it can lead to having many variables which will be repetitive in another classes too
#Value("${properties.user-id-length}")
private int userIdLength;
I also can access my configuration class (as it is Spring Bean) through #Autowire it to variable in every single class I need make use of it. The cons for that is that more complex configuration class containing inner classes, which contain inner classes etc. will not look too great in code
#Autowired // Not recommended, but for simplicity
private MyConfigurationClass myConfigurationClass;
// some method
int userIdLength = myConfigurationClass.getUserIdLength();
String serverLocation = myConfigurationClass.getAmazon().getSes().getSenderEmailAddress()
Another way is to create additional helper class like Constant and set needed static fields with #Value but it can be time consuming and I'm not sure it is THAT different from first solution
public static int USER_ID_LENGTH;
#Value("${properties.user-id-length}")
private void setUserIdLength(int length){
Constant.USER_ID_LENGTH = length;
}
So, which aproach is the best? Or are there another ways to do that?
Well, not much of the feedback but in the meantime I figured out that using both #Value and #ConfigurationProperties leads to some problems.
MyProp.class
#Getter
#Setter
#ConfigurationProperties(prefix = "prop")
public class MyProp{
private String default = "Default String"
}
SomeClass.class
#Component
public class SomeClass.class{
#Value("${prop.default}")
public String message;
}
Above example causes Exception BeanCreationException
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someClass': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'prop.default' in value "${prop.default}"
Explanation to this can be found here in #davidxxx's post and occurs unless we set all fields in application.properties. Because of that my first proposal cannot be done in the terms I thought it can be done and explanation was not easy to find, so I hope it will help someone one day.
I have some architecture issue.
I have two different interfaces (IntefaceA, IntefaceB) and a class (MyClass), which implements these.
When I inject MyClass like this:
#Autowired
InterfaceA myClass;
I am not able to use implemented methods from InterfaceB.
My idea was to check with the instanceof MyClass, to be able to call the method from InterfaceB, but currently autowired object as InterfaceA is not a (sub)-type from MyClass.
if(myClass instanceof MyClass) {
InterfaceB myClassFromInterfaceB =(InterfaceB) myClass;
result= myClassFromInterfaceB.methodFromInterfaceB
}
How can I autowire one object in spring, which can call all methods from all interfaces, which will be implemented by this object?
It is only possible to declare two different objects ?
If the code may be changed, the cleanest way would be creating an interface that is composed of these two interfaces and making your implementation class derive from it.
Then you can declare your field to inject with this super interface as type :
#Autowired
InterfaceAandB myClass;
If the code cannot be changed, as alternative declare two fields to autowire in your bean and specify different interface types for each field.
It will result to a same object injected twice but referenced by two variable with different interfaces :
#Autowired
InterfaceA myA;
#Autowired
InterfaceB myB;
I have a question regarding how to implement Marker interface through spring. I need to point my marker interface to its implemented classes. Itself marker interface dont have any of function declaration.
interface A {
/* No Method declaration */
}
#Component("c")
Class B implement A {
void function1(){ .. }
void function2(){ .. }
}
#Component("c")
Class C implement A {
void function3(){ .. }
void function4(){ .. }
}
Now Some where in my business Logic, i would like to use #Autowire though my interface to point any of one implementation.
#Autowired
#Qualifier("b")
A aB;
#Autowired
#Qualifier("c")
A aC;
It dont work. Will you please help to implement in correct way…! I was expecting thorugh reflection it should give me the list of method available in the implemented classes but it dont.
Added More Details
The only thing i would like to do is, I would like to reply IResponse to my business methods, instead of different tyoe. Its ok for me if i would have to #Authowired direct to implementation like
#Autowired
B aB;
but i thought if there is some way my IDE and Spring do some logic and when i #Autowired my interface towards implementation then it should be able to pick my Implementation class and should show me the business methods. Its not magic, when i am using qualified. I just want from spring to show me business methods through reflection.
What is the point of injecting A exactly? You probably expect Spring to do some kind of "magic" when it injects the dependency. It does not. I will simply inject the bean that you have required if it can inject it. In your case, the Qualifer value gives a hint as to which bean instance spring injects.
Except the typo (it's #Autowired, not #Autowire), this code should indeed inject B and C. But as you declared them as being A in your code you'll get a simple java.lang.Object basically. That's just a fundamental principle of Java that is strongly typed language.
Here is my singlton class using enum:
public enum MyInstanceFactory {
INSTANCE;
private SOMEOBJECT;
private int countInitialization = 0;
private MyInstanceFactory(){
countInitialization++;
System.out.println("WOW!! This has been initialized: ["+countInitialization+"] times");
SOMEOBJECT = SOMETHING
}
public Session getSomeobject(){ return SOMEOBJECT; }
}
Now I am calling it like inside MVC controller
Session cqlSession = MyInstanceFactory.INSTANCE.getSomeobject();
In this way it calls constructer only first time and next and onwards it return the correct value for SOMEOBJECT.
My question is I want to do the same thing when a spring application start i.e. initializing contructor once and use **getSomeobject** multiple times.
I saw THIS SO ANSWER but here they are saying
If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.
Will reflection create problem for a singlton class?
If you need a non-subvertible singleton class (not just a singleton bean that's shared by many other beans, but actually a singleton class where the class can only ever be instantiated once), then the enum approach is a good one. Spring won't try to instantiate the enum itself, because that really makes no sense; that would be a much more extremely broken thing to do than merely calling a private constructor.
In that case, to refer to the enum instance from Spring configuration, you do the same thing as for any other static constant; for example:
<util:constant static-field="MyInstanceFactory.INSTANCE" />
As Bloch states in Item 3 ("Enforce the singleton property with a private constructor or an enum type") of Effective Java 2nd Edition, a single-element enum type is the best way to implement a singleton. Unfortunately the old private constructor pattern is still very widespread and entrenched, to the point that many developers don't understand what I'm doing when I create enum singletons.
A simple // Enum Singleton comment above the class declaration helps, but it still leaves open the possibility that another programmer could come along later and add a second constant to the enum, breaking the singleton property. For all the problems that the private constructor approach has, in my opinion it is somewhat more self-documenting than an enum singleton.
I think what I need is an annotation which both states that the enum type is a singleton and ensures at compile-time that only one constant is ever added to the enum. Something like this:
#EnumSingleton // Annotation complains if > 1 enum element on EnumSingleton
public enum EnumSingleton {
INSTANCE;
}
Has anyone run across such an annotation for standard Java in public libraries anywhere? Or is what I'm asking for impossible under Java's current annotation system?
UPDATE
One workaround I'm using, at least until I decide to actually bother with rolling my own annotations, is to put #SuppressWarnings("UnusedDeclaration") directly in front of the INSTANCE field. It does a decent job of making the code look distinct from a straightforward enum type.
You can use something like this -
public class SingletonClass {
private SingletonClass() {
// block external instantiation
}
public static enum SingletonFactory {
INSTANCE {
public SingletonClass getInstance() {
return instance;
}
};
private static SingletonClass instance = new SingletonClass();
private SingletonFactory() {
}
public abstract SingletonClass getInstance();
}
}
And you can access in some other class as -
SingletonClass.SingletonFactory.INSTANCE.getInstance();
I'm not aware of such an annotation in public java libraries, but you can define yourself such a compile time annotation to be used for your projects. Of course, you need to write an annotation processor for it and invoke somehow APT (with ant or maven) to check your #EnumSingleton annoted enums at compile time for the intended structure.
Here is a resource on how to write and use compile time annotations.