Pregunta

Aquí está mi código:

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 esto? Consigo NullPointerException. Es posible el uso de Autowiring en una aplicación independiente?

¿Fue útil?

Solución

El resorte funciona en la aplicación independiente. Está utilizando el camino equivocado para crear un grano 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. Así que la primavera no tienen la oportunidad de Autowire las dependencias (que hace que el NullPointerException).

En el segundo caso (el de esta respuesta), se obtiene el grano del contexto primavera y por lo tanto es gestionado y primavera primavera se encarga de autowiring.

Otros consejos

Primavera se está alejando de archivos XML y los usos anotaciones fuertemente. El siguiente ejemplo es una simple aplicación de la primavera independiente que utiliza la anotación 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;
   }
}

Este es un grano simple. Está decorado con la anotación @Component para la detección automática por contenedor de primavera.

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. Las búsquedas @ComponentScan de anotación para los componentes. La anotación @Autowired inyecta el grano en la variable message. El AnnotationConfigApplicationContext se utiliza para crear el contexto de aplicación de primavera.

independiente primavera tutorial muestra cómo crear una aplicación de la primavera independiente con XML y anotaciones.

Para Spring 4, utilizando Spring Boot que puede tener el siguiente ejemplo sin utilizar el anti-patrón de conseguir el Bean de la ApplicationContext 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 sub-paquetes.

Una buena solución sería hacer siguiente,

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContext implements ApplicationContextAware {

private static ApplicationContext context;

/**
 * Returns the Spring managed bean instance of the given class type if it exists.
 * Returns null otherwise.
 * @param beanClass
 * @return
 */
public static <T extends Object> T getBean(Class<T> beanClass) {
    return context.getBean(beanClass);
}

@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {

    // store ApplicationContext reference to access required beans later on
    SpringContext.context = context;
}
}

A continuación, se puede usar como:

YourClass yourClass = SpringContext.getBean(YourClass.class);

Me pareció muy buena solución en la siguiente página web: https: // confluence.jaytaala.com/pages/viewpage.action?pageId=18579463

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top