72

これが私のコードです:

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ます。スタンドアロンアプリケーションで自動配線を使用することは可能ですか?

4

5 に答える 5

132

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

最初のケース (問題のケース) では、Spring コンテキストからオブジェクトを取得するのではなく、自分でオブジェクトを作成しています。Autowireそのため、Spring は依存関係にアクセスする機会がありません(これにより が発生しますNullPointerException)。

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

于 2010-09-07T15:02:41.583 に答える
29

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

シンプルな豆です。@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());
    }
}

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

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

于 2016-12-07T12:54:18.597 に答える
3

SpringBoot を実行している場合:

静的なメイン メソッドからサービスの 1 つを Autowire できないという同じ問題がありました。

SpringApplication.runに依存している場合は、以下のアプローチを参照してください。

@SpringBootApplication
public class PricingOnlineApplication {

    @Autowired
    OrchestratorService orchestratorService;

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(PricingOnlineApplication.class, args);
        PricingOnlineApplication application = context.getBean(PricingOnlineApplication.class);

        application.start();
    }

    private void start() {
        orchestratorService.performPricingRequest(null);
    }

}

SpringApplication.run は、上記のアプローチと同様に使用できるコンテキストを返すことに気付きました。そこからは、上記とまったく同じです;-)

于 2020-04-02T07:49:51.977 に答える