2010-09-07 12 views
56

Aquí está mi código:Usando Spring 3 Autowire en una aplicación Java independiente

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> 

¿Por qué no funciona? Obtengo NullPointerException. ¿Es posible utilizar el autoenvío en una aplicación independiente?

+0

Haz un esfuerzo para que tu pregunta sea legible. Y muéstranos el rastro de pila de excepción. – skaffman

+0

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

Respuesta

118

Spring funciona en una aplicación independiente. Estás usando la forma incorrecta para crear un bean de primavera. La forma correcta de hacerlo de esta manera:

@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"; 
    } 
} 

En el primer caso (el de la pregunta), que está creando el objeto por sí mismo, en lugar de obtenerlo a partir del contexto de primavera. Entonces Spring no tiene la posibilidad de Autowire las dependencias (que causa el NullPointerException).

En el segundo caso (el de esta respuesta), obtiene el bean del contexto de Spring y, por lo tanto, es Spring managed y Spring se encarga de autowiring.

+0

¿No es @Autowired una estrategia all-in? O bien la primavera administra _todos_ la creación de objetos ninguno, pero no puede agregar @Autowired a algunos campos en su pila de llamadas y crear instancias con nuevos ..(). – Cojones

+0

Si se crea una instancia de un solo objeto en su pila de llamadas con una nueva ..() no funcionará ¿no? – Cojones

+2

@Cojones, puede conectar automáticamente algunos beans y crear otros con nuevos; de lo contrario, ¿cómo podría llamar a 'new ArrayList()', por ejemplo? Si tienes una clase con parámetros autoconectados y la instanciaste con 'new', entonces el autoenvío no tendrá lugar. – Paul

12

Spring se está alejando de los archivos XML y usa anotaciones en gran medida. El siguiente ejemplo es una aplicación Spring simple e independiente que utiliza anotaciones en lugar de archivos 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; 
    } 
} 

Esto es un simple frijol. Está decorado con la anotación @Component para autodetección en contenedor 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()); 
    } 
} 

Esta es la clase principal Application. La anotación @ComponentScan busca componentes. La anotación @Autowired inyecta el bean en la variable message. El AnnotationConfigApplicationContext se usa para crear el contexto de la aplicación Spring.

Mi Standalone Spring tutorial muestra cómo crear una aplicación de Spring independiente con XML y anotaciones.

0

para la primavera 4, utilizando Spring arranque que puede tener el siguiente ejemplo sin utilizar el anti-patrón de conseguir el Bean desde el Application Context directamente:

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"; 
    } 
} 

Asegúrese de que todos sus servicios inyectados están bajo com.yourproject o sus subpaquetes.

Cuestiones relacionadas