Inconsistent circular dependency with constructor+setter injection - java

I have following beans in my application
#Component
public class Main {
private A a;
#Inject
public Main(A a) {
this.a = a;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
#Component
public class A {
private B b;
#Inject
public void setB(B b) {
this.b = b;
}
public B getB() {
return b;
}
}
#Component
public class B {
private A a;
#Inject
public void setA(A a) {
this.a = a;
}
public A getA() {
return a;
}
}
Component scan is for the package where this three classes were placed.
The above beans works in some environment and fails in other environment with circular dependency while create bean Main
Why is this circular dependency not very consistent?

The problem is that your bean A depends on bean B, and bean B depends on bean A. First of all, I would suggest rethinking your design. However, there are workarounds like using #Postconstruct, or #Lazy.
Here's a good reference, which explains what happens and different ways to solve the problem: http://www.baeldung.com/circular-dependencies-in-spring

Related

Prevent calling constructor - Mockito

Let's say I have classA and classB:
public class A {
private B b;
public A(String id){
this.b = new B(id);
}
public void doSomethingA(String id){
// do somethingA
}
}
public class B{
public B(String id){
// call anotherThing (id)
}
public void doSomethingB(){
//somethingB
}
}
now I want to test methods inside classA (with it's instance) but wanna mock classB
Mockito allows me to mock classB, but when I instantiate classA, the constructor calls classB (which I want to avoid)
Is there a way to mock only the constructor (either classA or classB) but not the other methods?
You may mock any B object but you don't want to.
You want to mock the B b field of the A class.
Which is different.
You have to refactor your design and do B instantiation a dependency and not an internal processing.
A simple way is passing directly the B variable instead of the String as parameter :
public class A {
private B b;
public A(B b){
this.b = b;
}
public void doSomethingA(String id){
// do somethingA
}
}
Now mocking is straight :
#Mock B b;
public void test(){
A a = new A(b);
}
An alternative way would be using a Function<String, B> .
public class A {
private B b;
public A(Function<String, B> bFunction, String id){
this.b = bFunction.apply(id);
}
public void doSomethingA(String id){
// do somethingA
}
}
Mocking becomes so :
#Mock B b;
public void test(){
A a = new A(s-> b, "anyValue");
}
And implementation code could instantiate A as :
A a = new A(B::new, "id");

Constructor based dependency injection inject property based objects

I have two classes
Class B {
#Resource
C c;
}
Class A {
private final B b;
public A(B b) {
this.b = b;
}
}
Then class A is initialized using Spring through #Bean annotation as follows:
#Configuration
public class AppConfigHelper {
#Bean
public C getC() {
return new C();
}
#Bean
public B getB() {
return new B();
}
#Bean
public A getA() {
return new A(getB());
}
}
The problem that I end up with is C getting null in object of type B. Is there a solution to this problem?
I have to get A initialized this way only as the B is the old code which I do not want to touch at this point of time.

Re-using same instance of prototype bean created by Spring

I am looking for a way to represent below code using spring dependency injection and comply to the solid principles.
A a = new A();
I b = new B(a);
I c = new C(a);
I d = new D(a);
Z z = new Z( Lists.newArrayList(b,c,d));
B, C and D are implementations on the same interface and a list of these is required for Z instantiation. Overall, there should be one new A instance per Z creation.
None of the objects can be a singleton, and I am stuck getting this translated to a spring xml configuration.
May you try to have a configuration like this one :
#Component
#Scope("prototype")
public class A {...}
#Component
#Scope("prototype")
public class B implements I {
private A a;
#Autowired
public B(A a) {
this.a = a;
}
}
#Component
#Scope("prototype")
public class C implements I {
private A a;
#Autowired
public C(A a) {
this.a = a;
}
}
#Component
#Scope("prototype")
public class D implements I {
private A a;
#Autowired
public D(A a) {
this.a = a;
}
}
public class Z {
#Autowired
private List<I> implementations;
}
Each implementations of I inject A directly in the constructor. Z inject all implementations if I.

Spring. Resolve circular dependency with java config and without #Autowired

I've got circular dependency and java config. While resolving it with xml config is very easy I can't resolve it with java config without #Autowired. Beans:
public class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
public class B {
private A a;
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
I've tried this(I've read that with #Bean annotation Spring won't invoke method every time bean is referenced, but in this case it's actually been invoked all the time):
#Configuration
public class Config {
#Bean
public A a() {
A a = new A();
a.setB(b());
return a;
}
#Bean
public B b() {
B b = new B();
b.setA(a());
return b;
}
}
And this, with #Autowired of Configuration class fields:
#Configuration
public class Config {
#Autowired
A a;
#Autowired
B b;
#Bean
public A a() {
A a = new A();
a.setB(b);
return a;
}
#Bean
public B b() {
B b = new B();
b.setA(a);
return b;
}
}
Also I've tried all above with #Lazy annotation. Doesn't help. But works perfectly if I annotate setters of A and B with #Autowired. But it's not what I want right now. What am I doing wrong and is there any way to resolve Circular dependency in java config without usage of #Autowired?
The behavior you want to get is the following
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
#Bean methods don't give you that. They run to completion to provide a bean instance.
You basically have to partially create one of the instances, then finish initializing it when you've created the other.
#Configuration
class Config {
#Bean
public A a() {
A a = new A();
return a;
}
#Bean
public B b() {
B b = new B();
A a = a();
b.setA(a);
a.setB(b);
return b;
}
}
or
#Bean
public B b(A a) {
B b = new B();
b.setA(a);
a.setB(b);
return b;
}
Another approach using #Autowired and #Component is to use this pattern:
#Component
class A {
private B b;
public B getB() {
return b;
}
public void setB(final B b) {
this.b = b;
}
}
#Component
class B {
private final A a;
#Autowired
public B(final A a) {
this.a = a;
a.setB(this);
}
public A getA() {
return a;
}
}
This eliminates the need for a separate #Configuration-class. Furthermore, the setB-method can possibly be package-protected if the classes exist in the same package to minimize scoping as much as possible.
I want to add another possible solution for your code. Instead of setting circular dependencies right in the config:
#Configuration
public class Config {
#Bean
public A a() {
A a = new A();
a.setB(b());
return a;
}
#Bean
public B b() {
B b = new B();
b.setA(a());
return b;
}
}
You could also let the spring do the work with the power of #Autowired annotation.
#Configuration
public class Config {
#Bean
public A a() {
A a = new A();
return a;
}
#Bean
public B b() {
B b = new B();
return b;
}
}
public class A {
private B b;
#Autowired
public setB(B b) { this.b = b; }
}
public class B {
private A a;
#Autowired
public setA(A a) { this.a = a; }
}
Of course it is non trivial from the "clean/readable/understandable" point of view because now your configuration is mixed in #Configuration and class itself. But as circular dependencies are quite rare, we could afford the hack.

How to initialize a circular dependency (final fields referencing each other)?

How do you initialize this:
class A {
final B b;
A(B b) {
this.b = b;
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
DI framework, reflection, better design?
Motivation and a use case (added):
My particular use case is simplifying field access in A's and B's sub-classes. So I'm injecting them to shortly reference them by fields in the derived classes without a need to declare explicitly in each sub-class.
There is also a recommendation on DI that objects should better be immutable: Guice best practices and anti-patterns.
You could use a factory method
class A {
final B b;
A(B b) {
this.b = b;
}
}
abstract class B {
final A a;
B() {
this.a = constructA();
}
protected abstract A constructA();
}
public class C {
public static void main(String []args){
new B(){
protected A constructA(){
return new A(this);
}
};
}
}
Though it may look dirty, but I prefer to replace one of the final references with Supplier (like one in Guava or Java 8) like:
class A {
final Supplier<B> b;
A(Supplier<B> b) {
this.b = b;
}
// keeping this constructor just for usability's sake
A(B b) {
this.b = ofInstance(b); // using Guava's Suppliers.ofInstance here
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
public static void main(String[] args) {
// using MutableSupplier.create() static factory method
MutableSupplier<B> bRef = create();
A a = new A(bRef);
B b = bRef.set(new B(a));
}
where MutableSupplier looks somehow like the following:
import com.google.common.base.Supplier;
public class MutableSupplier<T> implements Supplier<T> {
private boolean valueWasSet;
private T value;
private MutableSupplier() {
}
#Override
public T get() {
if (!valueWasSet) {
throw new NullPointerException("Value has not been set yet");
}
return value;
}
public T set(final T value) {
if (valueWasSet) {
throw new IllegalStateException("Value has already been set and should not be reset");
}
this.value = value;
this.valueWasSet = true;
return value;
}
public static <T> MutableSupplier<T> create() {
return new MutableSupplier<T>();
}
}
I know that MutableSupplier's mutability looks super-ugly for immutability enthusiasts but I found that using it is more or less acceptable in such cases :)
What you are having is a circular dependency. The only way I can think of is to not declare the fields as final and have your dependency injected using setter injection instead of constructor injection.
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);

Categories

Resources