0

I'm starting with Spring. I got to work with a provided @RestController-Application and I thougt I got it. Now I try to work with a POJO and cannot get @Autowire working. This is my environment:

The Bean:

package mybeans;

import org.springframework.stereotype.Repository;

@Repository
public class User {
    private String surname;
    private String lastname;
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
}

The Code

package mycode;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import mybeans.User;

@Component
public class Main {

    private User user;

    @Autowired
    public void setUser(User user) {
        this.user=user;
    }

    public Main() {
        System.out.println("autowired user is instantiated true/false: " + !(user==null));
    }

    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
//      User user=(User) context.getBean("user");
//      System.out.println("explicit user is instantiated true/false: " + !(user==null));
        new Main();

    }

}

The Context-xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- enable autowire -->
    <context:annotation-config />

    <context:component-scan base-package="mybeans" />

    <!--  
    <bean id="user" class="mybeans.User" autowire="byName">
        <property name="surname" value="Ulrich" />
        <property name="lastname" value="Schmidt" />
    </bean>
    -->

</beans>

The bean "user" never becomes instantiated, even when exlicit defining the bean (is a comment now). Does anybody see, whats wrong here? Thanks a lot

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Ulrich
  • 715
  • 2
  • 7
  • 25
  • I don't understand, how do you verify that the bean named `user` isn't initialized? – Sotirios Delimanolis Jan 06 '16 at 22:09
  • 1
    Try remove comment for bean – Abdelhak Jan 06 '16 at 22:13
  • Verified this with debug; and the System.out.println indicates that "user" is always null! – Ulrich Jan 06 '16 at 22:16
  • 1
    The constructor in a `@Component` class is called before the autowiring of the atributes/methods. Create another method and add your sysout on it also annotate it with `@PostConstruct` – Jorge Campos Jan 06 '16 at 22:18
  • I tried with another class, called from Main as well, just to see the effect. Anyway; the class Main is instantiated after context-load; the injection is done when class is instantiated; so I don't think that a separate class will make a difference. The "context.getBean()" works; but I would prefer @Autowired to get run. – Ulrich Jan 06 '16 at 22:23
  • Not in a separate class in the same Main class add another method, say `@PostConstruct public void testMethod(){ System.out.println("auto...."); }` – Jorge Campos Jan 06 '16 at 22:25
  • 1
    You are using setter-based injection but your test is on the constructor. Autowired setters are only invoked after the constructor completes. So either (i) use constructor-based injection (Autowire the Main() constructor) or (ii) use @PostConstruct to test for values after the constructor is completed. – KarlM Jan 06 '16 at 22:26
  • @Jorge: Doesn't make a difference. Neiter calling the method from the constructor nor from the main-method does change anything here. – Ulrich Jan 06 '16 at 22:29
  • 2
    Because `new Main();` is not a Spring bean. Read http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null. Check the `Main` bean from your `ApplicationContext`. – Sotirios Delimanolis Jan 06 '16 at 22:30
  • I just noticed a thing, that is in fact a problem – Jorge Campos Jan 06 '16 at 22:31
  • Your component-scan tag is scanning `` only mybeans package which means that it will not scan your main class that is on the `mycode` package, either add this package on the scan or move a class into the same package – Jorge Campos Jan 06 '16 at 22:33
  • @Jorge: added the mycode to the scan context. But my understanding is, that the component-scan detects the beans. The injection is done by the annotation; there should not be a need to add the code also to the scan. I tried it anyway; nothing changed – Ulrich Jan 06 '16 at 22:52
  • @Sotiros: the described samples run with Spring-MVC; as I said in the beginning the web-applications using MVC are fine. I would like to understand whats wrong with my code here. I described my understanding of the automatic injection in the previous answer. – Ulrich Jan 06 '16 at 22:58
  • When you use the `annotation-config` configuration, the spring will only inject classes with `@Component` or inheritances of it like `@Repository` So your main class would not be added to the context cause it was in the package scan. I will try to reproduce your problem here! – Jorge Campos Jan 06 '16 at 22:58
  • I will check tomorroy again. It's midnight here; need to have a bit of sleep – Ulrich Jan 06 '16 at 23:03
  • The MVC part of it is irrelevant. A `@Controller` is just a bean and follows the same rules as `@Repository`, `@Component` and any other meta-component annotation. It's all the same. – Sotirios Delimanolis Jan 06 '16 at 23:06
  • See it here: http://imagebin.ca/v/2SZax2DonCXo working example, properly configured! – Jorge Campos Jan 06 '16 at 23:07
  • Ignore everything else, as I used a project that had the needed dependencies. – Jorge Campos Jan 06 '16 at 23:08
  • @Jorge: Thanks a lot. This works fine. My approach was not working, at least I think so now, because I defined the "Main" as bean as you said, but I instantiated it myself. It has all to be done by Spring. – Ulrich Jan 07 '16 at 21:34

0 Answers0