Spring injects @Autowired fields during manual class instantiation

how to autowire parameterized constructor in spring boot
spring boot inject programmatically
spring value constructor injection
spring autowired optional
always use constructor based dependency injection
spring boot autowired
spring component constructor
org springframework beans factory annotation autowired(required=true in spring boot)

In my project I am surprised to see that Spring (4.3) seems to attempt to autowire dependencies for classes even when they are manually instantiated.

MyClass.java (note Lombok annotations):

@NoArgsConstructor
@AllArgsConstructor
public class MyClass {
    @Autowired
    private MyClassDependency dependency;
}

MyClassDependency.java uses a factory method and no Spring annotations:

public class MyClassDependency {
    public static MyClassDependency create() { return new MyClassDependency(); }
}

Spring config resulting in NoSuchBeanDefinitionException:

@Configuration
public class SpringConfig {
    @Bean
    public MyClass myClass() {
        return new MyClass(MyClassDependency.create());
    }
}

Providing the bean makes Spring happy:

@Configuration
public class SpringConfig {
    @Bean
    public MyClass myClass() {
        return new MyClass(); // let autowire inject dependencies
    }
    @Bean
    public MyClassDependency myClassDependency() {
        return MyClassDependency.create();
    }
}

This was a big surprise to me. I'd like to have the simpler first version of the config... Where is this behavior coming from / controlled? (It's possible that I missed it or pulled it from some dependencies).

PS: To clarify, MyClass code is outside of my control but I can change Spring config. I am looking to understand how Spring intercepts the constructor call withing a bean method and whether constructor can be used instead.

The problem is the following:

  1. You annotated a field with @Autowired - that tells Spring, that there is a dependency that needs to be injected there
  2. You annotated a method with @Bean - which puts the return value into Spring's context.
  3. When Spring processes the return value of the @Bean-annotated object, it starts to proces its annotations - and there is a field with an annotation, that tells Spring to inject a dependency there, even if the field already has a value assigned.
  4. Spring tries to inject the dependency here, but that dependency does not exist in the Spring context, so injection fails.

So having @Bean, but manually injecting an @Autowired dependency conflicts each other, you may now understand, why - you shall not inject Autowired beans manually! Autowired is an annotation that tells he CI container to do some injection work.

Spring Dependency Injection with Example, can't be used to inject primitive and string values. It works with reference only. This Spring Framework article will demonstrate the use of annotations related to dependency injection, namely the @Resource, @Inject, and @Autowired annotations. These annotations provide classes with a declarative way to resolve dependencies. For example: @Autowired ArbitraryClass arbObject;

There's a hacky way of doing that, as described in this old Stack Overflow thread.

public static <T> FactoryBean<T> preventAutowire(T bean) {
    return new FactoryBean<T>() {
        public T getObject() throws Exception {
            return bean;
        }

        public Class<?> getObjectType() {
            return bean.getClass();
        }

        public boolean isSingleton() {
            return true;
        }
    };
}

...

@Bean
static FactoryBean<MyBean> myBean() {
    return preventAutowire(new MyBean());
}

how to use @Autowired in the test methods, . Your classes have tight coupling with your DI container and cannot be used outside of it. Your classes cannot be instantiated (for example in unit tests) without reflection. Overview I’ve been asked several times to explain the difference between injecting Spring beans with ‘@Resource’, ‘@Autowired’, and ‘@Inject’. While I received a few opinions from colleagues and read a couple of posts on this topic I didn’t feel like I had a complete picture.

Let's clarify further a bit on what answers like Celebi pointed out.

Your surprise at how it behaves seems to stem from looking at a portion of the wiring behavior backwards, versus how it works.

You wrote:

..I am surprised to see that Spring (4.3) seems to attempt to autowire dependencies for classes even when they are manually instantiated.

It is not trying to wire the non-bean "MyClassDependency" class without it having a @Bean notation. In fact from the Spring perspective it does not "see" that class at all.

The other side of the code is Asking for a bean of class name "MyClassDependency" - That is what is initiating the attempt to go find "MyClassDependency" and create a wiring. Of course, it does not find any matching bean of that name/criteria.

Your question seems more regarding the need to understand why it is behaving in the manner you observed and I believe this is why.

Functionally, you likely already solved your own problem. By adding @Bean on top of MyClassDependency, for Spring you now have a visible bean available for use by the other code requesting it.

Autowiring in Spring, Spring injects @Autowired fields during manual class instantiation. how to autowire parameterized constructor in spring boot spring autowired optional spring  If you want/need to get a new instance of SomeRepo every time CreatingRepo#postMessage is executed and by using new operator and let Spring manages the instance of the bean (this is, enabling autowiring capabilities and other Spring goods) you could use @Configurable. – Luiggi Mendoza Nov 16 '15 at 16:53

You should use AbstractFactoryBean as in this example

package com.stackoverflow.q53737175;

import static org.junit.Assert.*;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@SuppressWarnings("javadoc")
public class Answer {

    /** The Constant SPRING_CLASS_RULE. */
    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    /** The spring method rule. */
    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    @Autowired
    MyClass myClass;

    @Test
    public void test() {
        assertNotNull(this.myClass);
    }

    @Configuration
    static class SpringConfig {

        @Bean
        public FactoryBean<MyClass> myClass() {

            return new AbstractFactoryBean<MyClass>() {

                @Override
                public Class<?> getObjectType() {

                    return MyClass.class;
                }

                @Override
                protected MyClass createInstance() throws Exception {

                    return new MyClass(MyClassDependency.create());
                }

            };
        }
    }

    @NoArgsConstructor
    @AllArgsConstructor
    static class MyClass {

        @Autowired
        private MyClassDependency dependency;
    }

    static class MyClassDependency {
        public static MyClassDependency create() {
            return new MyClassDependency();
        }
    }
}

What exactly is Field Injection and how to avoid it?, as opposed to instantiating them directly (the imperative way), for example: ? Constructor Dependency Injection in Spring Learn the differences of using @​Autowired on abstract classes vs. concrete classes Resolving dependencies by field injection is achieved by annotating an instance variable with  Apart from the @Autowired annotation, Spring can use XML-configurable autowiring. In that case all fields that have a name or type that matches with an existing bean automatically get a bean injected. In fact, that was the initial idea of autowiring - to have fields injected with dependencies without any configuration.

The behavior is coming from the @Bean annotation definition:

1.12.1. Basic Concepts: @Bean and @Configuration

The central artifacts in Spring’s new Java-configuration support are @Configuration-annotated classes and @Bean-annotated methods.

The @Bean annotation is used to indicate that a method instantiates, configures, and initializes a new object to be managed by the Spring IoC container. For those familiar with Spring’s <beans/> XML configuration, the @Bean annotation plays the same role as the <bean/> element. You can use @Bean-annotated methods with any Spring @Component. However, they are most often used with @Configuration beans.

preventAutowire proposed by Fabio Manzano is an acceptable workaround until another solution is provided by Spring.

Spring injects @Autowired fields during manual class instantiation, The container then injects those dependencies when it creates the bean. Your application classes are combined with configuration metadata so that after tell the Spring container to instantiate, configure, and assemble the objects in your use the standard Java convention for instance field names when naming beans. *In regards to point #3 above, I am aware that the org.springframework.boot:spring-boot-starter-aop transitively pulls the spring-aop (as shown here mavencentral) but, in my case the Eclipse failed to resolve the @EnableSpringConfigured annotations hence, why I explicitly added the spring-aop dependency in addition to the starter. Should you face the same issue, just declare the dependency or

Wiring in Spring: @Autowired, @Resource and @Inject, Injecting a Validator; Configuring Custom Constraints; Spring-driven Method Validation Bean metadata and manually supplied singleton instances need to be is to use the standard Java convention for instance field names when naming beans. For more flexibility, including the ability to autowire fields and multiple  The main advantage of constructor-based injection is that you can declare your injected fields final, as they will be initiated during class instantiation. This is convenient for required dependencies. Setter-based dependency injection. In setter-based dependency injection, setter methods are annotated with @Autowired. Spring container will

3. The IoC container - Project Metadata API Guide, They are known in the Spring context and can be used for injection. Order of execution. When a constructor of a class is called, the @Autowired instance example manually calling a constructor, the instance of the class will  Starting with Spring 2.5, the framework introduced a new style of Dependency Injection driven by @Autowired Annotations. This annotation allows Spring to resolve and inject collaborating beans into your bean.

Core Technologies - Project Metadata API Guide, java; spring; autowire; inject; dependency injection The problem with field injection is that you are allowed to instantiate a class in an invalid state. be thinking that there's no need to instantiate Spring beans manually. One solution would be to replace the auto-wiring with a manual lookup in the spring context. private DAO2 dao2 = SpringApplicationContext.getApplicationContext ().getBean (DAO2.class); @Autowired is working in @AppImpl because it's annotated as @Component. This flags it up for spring during its classpath scan where it will create an instance of

Comments
  • Remove @Autowired from the field if you don't need it. The fact that you use constructor injection should be enough. So remove the default constructor, leave only the one taking the dependency and remove @Autowired from your class.
  • by removing @Autowired on private MyClassDependency dependency; should work
  • Sorry I should have clarified - MyClass is the class outside of my control. I only control Spring config.
  • can you differentiate these two use cases? @alexandroid
  • Thank you! I missed the fact that Spring builds the dependency tree from the leaves up, so on #3 it will look for the dependency to auto-wire and ignore the method implementation I provided for it.
  • Thank you, but I wasn't really looking for the work around, I was trying to understand why Spring ignores my method implementation and looks for the dependency... I missed the fact that it builds them from the leaves of the tree up.
  • Thanks! I guess I was thrown off by the fact that Spring went to build the dependency tree and instantiate dependency, ignoring the implementation of the @Bean method I provided...
  • Thank you, but a workaround is not what I was looking for. I was looking to understand the Spring behavior in this case.
  • See, that's the part which was confusing to me - I thought that by annotating a method with @Bean I will tell Spring to call that method in order to instantiate that object and ignore the @Autowired parts of it. It looks like Spring did not run that method but saw @Autowired and kept building the dependency tree down, then looking for definitions of dependencies bottom up.
  • Thanks! Yes, that's the part which was confusing to me - I thought that by annotating a method with @Bean I will tell Spring to call that method in order to instantiate that object and ignore the @Autowired inside of it. It looks like Spring did not run that method but saw @Autowired and kept building the dependency tree down, then looking for definitions of dependencies bottom up.