ここに私のコードがあります:
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
を取得します。スタンドアロンアプリケーションで自動配線を使用することはできますか?
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
を処理します。
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アプリケーションを作成する方法を示しています。
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
またはそのサブパッケージの下にあることを確認してください。