2010-09-07 12 views
56

Qui è il mio codice:Utilizzando Spring 3 autowire in un alone un'applicazione Java

public class Main { 

    public static void main(String[] args) { 
     Main p = new Main(); 
     p.start(args); 
    } 

    @Autowired 
    private MyBean myBean; 
    private void start(String[] args) { 
     ApplicationContext context = 
      new ClassPathXmlApplicationContext("META-INF/config.xml"); 
     System.out.println("my beans method: " + myBean.getStr()); 
    } 
} 

@Service 
public class MyBean { 
    public String getStr() { 
     return "string"; 
    } 
} 

<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-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
    <context:annotation-config /> 
    <context:component-scan base-package="mypackage"/> 
</beans> 

Perché non fa questo lavoro? Ottengo NullPointerException. È possibile utilizzare l'autowiring in un'applicazione standalone?

+0

Fare uno sforzo per rendere la vostra domanda leggibile. E mostraci la traccia dello stack delle eccezioni. – skaffman

+0

Mantengo un esempio operativo qui: http://tshikatshikaaa.blogspot.com/2012/08/spring-ioc-container-with-annotations.html – JVerstry

risposta

118

La molla funziona in modalità standalone. Stai utilizzando il modo sbagliato per creare un fagiolo di primavera. Il modo corretto per farlo in questo modo:

@Component 
public class Main { 

    public static void main(String[] args) { 
     ApplicationContext context = 
      new ClassPathXmlApplicationContext("META-INF/config.xml"); 

     Main p = context.getBean(Main.class); 
     p.start(args); 
    } 

    @Autowired 
    private MyBean myBean; 
    private void start(String[] args) { 
     System.out.println("my beans method: " + myBean.getStr()); 
    } 
} 

@Service 
public class MyBean { 
    public String getStr() { 
     return "string"; 
    } 
} 

Nel primo caso (quello in questione), si sta creando l'oggetto da soli, piuttosto che ottenere dal contesto primavera. Quindi la primavera non ha la possibilità di Autowire le dipendenze (che causa il NullPointerException).

Nel secondo caso (quello in questa risposta), si ottiene il bean dal contesto Spring e quindi è gestito da Spring e Spring si occupa di autowiring.

+0

Non è @Autowired una strategia all-in? O molla gestisce _all_ la creazione dell'oggetto nessuno, ma non puoi aggiungere @Autowired ad alcuni campi nel tuo callstack e istanziarli con nuovi ..(). – Cojones

+0

Se solo un singolo oggetto nel tuo callstack viene istanziato con new ..() non funzionerà correttamente? – Cojones

+2

@Cojones, puoi autowire alcuni bean e crearne altri con nuovi, altrimenti come saresti mai in grado di chiamare 'new ArrayList()', ad esempio? Se hai una classe con parametri autowired e la installi con 'new', la procedura di autowiring non avrà luogo. – Paul

12

Spring si sta allontanando dai file XML e utilizza le annotazioni pesantemente. L'esempio seguente è una semplice applicazione autonoma Spring che utilizza l'annotazione invece dei file XML.

package com.zetcode.bean; 

import org.springframework.stereotype.Component; 

@Component 
public class Message { 

    private String message = "Hello there!"; 

    public void setMessage(String message){ 

     this.message = message; 
    } 

    public String getMessage(){ 

     return message; 
    } 
} 

Questo è un bean semplice. È decorato con l'annotazione @Component per il rilevamento automatico dal contenitore Spring.

package com.zetcode.main; 

import com.zetcode.bean.Message; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.ComponentScan; 

@ComponentScan(basePackages = "com.zetcode") 
public class Application { 

    public static void main(String[] args) { 

     ApplicationContext context 
       = new AnnotationConfigApplicationContext(Application.class); 

     Application p = context.getBean(Application.class); 
     p.start(); 
    } 

    @Autowired 
    private Message message; 
    private void start() { 
     System.out.println("Message: " + message.getMessage()); 
    } 
} 

Questa è la classe principale Application. L'annotazione @ComponentScan cerca i componenti. L'annotazione @Autowired inietta il bean nella variabile message. Lo AnnotationConfigApplicationContext viene utilizzato per creare il contesto dell'applicazione Spring.

Il mio Standalone Spring tutorial mostra come creare un'applicazione Spring autonoma con XML e annotazioni.

0

Per la Primavera 4, utilizzando Primavera Boot possiamo avere il seguente esempio senza utilizzare l'anti-modello di ottenere il fagiolo dalla ApplicationContext direttamente:

package com.yourproject; 

@SpringBootApplication 
public class TestBed implements CommandLineRunner { 

    private MyService myService; 

    @Autowired 
    public TestBed(MyService myService){ 
     this.myService = myService; 
    } 

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

    @Override 
    public void run(String... strings) throws Exception { 
     System.out.println("myService: " + MyService); 
    } 

} 

@Service 
public class MyService{ 
    public String getSomething() { 
     return "something"; 
    } 
} 

Assicurarsi che tutti i servizi iniettati sono sotto com.yourproject o i suoi sotto-pacchetti.

Problemi correlati