2016-07-20 15 views
8

Nie rozumiem, jak działa wiosenny opis adnotacji @Autowired poprawnie. Oto prosty przykład:Zrozumienie rozruchu sprężynowego @Autowired

@SpringBootApplication 
public class App { 
    @Autowired 
    public Starter starter; 

    public static void main(String[] args) { 
     SpringApplication.run(App.class, args); 
    } 
    public App() { 
     System.out.println("init App"); 
     //starter.init(); 
    } 
} 

-

@Repository 
public class Starter { 
    public Starter() {System.out.println("init Starter");} 
    public void init() { System.out.println("call init"); } 
} 

Kiedy wykonanie tego kodu, otrzymuję dzienniki init App i init Starter, więc wiosna tworzyć to obiekty. Ale kiedy wywołuję metodę init od Starter w App, otrzymuję NullPointerException. Czy jest jeszcze coś, co muszę zrobić, aby użyć adnotacji @Autowired do zainicjowania mojego obiektu?

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'app': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [{package}.App$$EnhancerBySpringCGLIB$$87a7ccf]: Constructor threw exception; nested exception is java.lang.NullPointerException 
+0

W zależności od zakresu swojej fasoli, ponieważ Wiosna Aplikacja rozruchowa jest wstępnie skonfigurowana do skanowania pakietów, a sprężyna tworzy instancję komponentu, którego chcesz użyć. Jednak tylko dlatego, że został stworzony, nie musi oznaczać, że został on wstrzyknięty. – christopher

Odpowiedz

12

Po wywołaniu metody z konstruktora klasy Appinit, wiosna jeszcze nie autowired zależności do obiektu App. Jeśli chcesz wywołać tę metodę po Wiosna zakończeniu tworzenia i autowiring obiekt App, następnie dodać metodę z @PostConstruct adnotacji to zrobić, na przykład:

@SpringBootApplication 
public class App { 
    @Autowired 
    public Starter starter; 

    public static void main(String[] args) { 
     SpringApplication.run(App.class, args); 
    } 

    public App() { 
     System.out.println("constructor of App"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("Calling starter.init"); 
     starter.init(); 
    } 
} 
+0

To ma sens. Teraz działa, dziękuję. Dlatego zawsze musisz użyć adnotacji @PostConstruct, aby uzyskać dostęp do obiektu z autyzmowaniem. –

+0

Zobacz także wpis na blogu Olivera Gierkesa: http://olivergierke.de/2013/11/why-field-injection-is-evil/ –

+0

@ daniel.eichten Zgadzam się, że wstrzyknięcie konstruktora jest lepsze niż wstrzyknięcie do pola, ale to oddzielny problem od tego, o co chodziło w tym pytaniu. – Jesper

Powiązane problemy