在独立的Java应用程序中使用Spring 3 autowire

mik*_*e27 69 java spring program-entry-point dependency-injection autowired

这是我的代码:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?我得到NullPointerException.是否可以在独立应用程序中使用自动装配?

Abh*_*kar 128

Spring适用于独立应用程序.您使用错误的方法来创建一个spring bean.这样做的正确方法:

@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";
    }
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下(问题中的那个),您自己创建对象,而不是从Spring上下文中获取它.所以Spring没有机会获得Autowire依赖(导致NullPointerException).

在第二种情况下(这个答案中的那个),你从Spring上下文中获取bean,因此它是Spring管理的,Spring负责autowiring.

  • 您可能还需要在config.xml中使用它:`<context:annotation-config /> <context:component-scan base-package ="com.yourcompany.mycomponents"/>` (5认同)
  • @Cojones,你可以自动装配一些bean并用new创建其他bean,否则你怎么能够调用`new ArrayList()`?如果你有一个带有自动装配参数的类,并用`new`实例化它,那么自动装配将不会发生. (2认同)
  • 不要忘记Main上面的@Component注释,否则你会得到一个没有类型[..]的限定bean定义的异常.花了一些时间才弄明白. (2认同)

Jan*_*nar 22

Spring正逐渐远离XML文件并大量使用注释.以下示例是一个简单的独立Spring应用程序,它使用注释而不是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;
   }
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的豆子.它装饰有@ComponentSpring容器自动检测的注释.

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是主要的Application课程.该@ComponentScan注释搜索组件.该@Autowired注释注入豆成message变量.将AnnotationConfigApplicationContext用于创建Spring应用程序上下文.

My Standalone Spring教程展示了如何使用XML和注释创建独立的Spring应用程序.


Mic*_*dis 11

对于Spring 4,使用Spring Boot我们可以使用以下示例,而不使用直接从ApplicationContext获取Bean的反模式:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

确保所有注入的服务都在com.yourproject其子包或其子包中.