web-dev-qa-db-ja.com

スタンドアロンJavaアプリケーションでSpring 3 autowireを使用する

ここに私のコードがあります:

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>

なぜこれが機能しないのですか? NullPointerExceptionを取得します。スタンドアロンアプリケーションで自動配線を使用することはできますか?

68
mike27

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

最初のケース(質問の1つ)では、Springコンテキストからオブジェクトを取得するのではなく、自分でオブジェクトを作成しています。そのため、SpringはAutowire依存関係(NullPointerExceptionを引き起こす)の機会を得ません。

2番目のケース(この回答の1つ)では、SpringコンテキストからBeanを取得するため、Springが管理され、Springがautowiringを処理します。

127
Abhinav Sarkar

SpringはXMLファイルから離れつつあり、アノテーションを多用しています。次の例は、XMLファイルの代わりに注釈を使用する単純なスタンドアロンSpringアプリケーションです。

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

これは単純なBeanです。 Springコンテナによる自動検出のために@Componentアノテーションで装飾されています。

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());
    }
}

これはメインのApplicationクラスです。 @ComponentScanアノテーションはコンポーネントを検索します。 @Autowiredアノテーションは、Beanをmessage変数に挿入します。 AnnotationConfigApplicationContextは、Springアプリケーションコンテキストの作成に使用されます。

My Standalone Spring tutorial は、XMLと注釈の両方を使用してスタンドアロンSpringアプリケーションを作成する方法を示しています。

20
Jan Bodnar

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

挿入するすべてのサービスがcom.yourprojectまたはそのサブパッケージの下にあることを確認してください。

10