Antoniossss
Antoniossss

Reputation: 32517

Why does Spring treat constructor injection differently than setter/field injection?

I've come across a small problem with a circular dependency in project and found out that using @Autowired on a field/setter can fix that instead of using @Autowired on a constructor. The conclusion of such behavior is that Spring injects proxies in the case of field/setter injections, and actual beans in the case of constructor injection.

The question: What is the reasoning behind this? Why different entities are injected?

Consider simple snippet:

    @Component
    public static class A{
        @Autowired B b;
        @Autowired C c;
    }
    @Component
    public static class B{
        @Autowired B b;
        @Autowired C c;
//      public B(C c,B b) { // this would cause circular dep problem
//          this.c=c;
//      }
    }
    @Component
    public static class C{
        @Autowired A a;
        @Autowired B b;
    }

One of ideas that comes into my mind is that with constructor injection, you are able to use injected entities right away, thus as a precaucion initialized beans are injected instead of proxies but on the other hand, I can do the same in case of setter approach, so that seams to be invalid.

Upvotes: 1

Views: 194

Answers (1)

marok
marok

Reputation: 2146

So when you used constructor injection all beans which are used in constructor must be created earlier. If you have circular dependencies then they can not be created because of this cirular dependencies and spring throw exception.

When you use setter/field injection injected element are set after creation of bean, so cirular depenecies are allowed.

BTW if you have circular dependecies try to redesign you application, because your code will be harder to maintain. It's one of reason why constructor injection should be preferred.

Upvotes: 2

Related Questions