私がしたいのは、NotesPanelクラスのフィールドbackgroundGrayを自動配線することだけですが、以下の例外しか得られません。
それで、問題は、それを正しく自動配線する方法ですか?それはおそらく私が間違っている何か非常に愚かなものだからです...
助けてくれてありがとう!トルステン
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'notepad' defined in class path resource [Beans.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [notepad.Notepad]: Constructor threw exception; nested exception is Java.lang.NullPointerException
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [notepad.Notepad]: Constructor threw exception; nested exception is Java.lang.NullPointerException
Caused by: Java.lang.NullPointerException
at notepad.NotesPanel.<init>(NotesPanel.Java:23)
at notepad.Notepad.<init>(Notepad.Java:18)
クラスメモ帳:
package notepad;
import Java.awt.BorderLayout;
import Java.awt.Dimension;
import javax.swing.JFrame;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Notepad
{
public Notepad()
{
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new NotesPanel(), BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(1024, 768));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
context.getBean("notepad");
}
}
クラスノートスパネル:
package notepad;
import Java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import org.springframework.beans.factory.annotation.Autowired;
public class NotesPanel
extends JPanel
{
JTextPane tPane = new JTextPane();
@Autowired
private BackgroundGray backgroundgray;
public NotesPanel()
{
// backgroundgray = new BackgroundGray();
// backgroundgray.setGray("200");
setLayout(new BorderLayout());
tPane.setBackground(backgroundgray.getGrayObject());
add(tPane, BorderLayout.CENTER);
tPane.setText("Fill me with notes... ");
}
}
クラスBackgroundGray:
package notepad;
import Java.awt.Color;
public class BackgroundGray
{
String gray;
public BackgroundGray()
{
System.out.println("Background Gray Constructor.");
}
public String getGray()
{
return gray;
}
public void setGray(String gray)
{
this.gray = gray;
}
public Color getGrayObject()
{
int val = Integer.parseInt(gray);
return new Color(val, val, val);
}
}
Beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<context:annotation-config />
<bean id="notepad" class="notepad.Notepad"/>
<bean id="backgroundgray" class="notepad.BackgroundGray" autowire="byName">
<property name="gray" value="120"></property>
</bean>
</beans>
Springサポート@Autowire
、... Spring Beansのみ。通常、Javaクラスは、Springによって作成されるとSpring Beanになりますが、new
では作成されません。
回避策の1つは、クラスに@Configurable
の注釈を付けることですが、AspectJ(コンパイル時またはロード時の手を振る)を使用する必要があります。
@see Springの@Configurable
を3つの簡単なステップで使用する 短いステップバイステップの説明。
新規でオブジェクトを作成すると、autowire\injectが機能しません...
回避策として、これを試すことができます:
notesPanelのテンプレートBeanを作成する
<bean id="notesPanel" class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
このようにしてインスタンスを作成します
context.getBean("notesPanel");
[〜#〜] prototype [〜#〜]:これは、任意の数のオブジェクトインスタンスを持つように単一のBean定義のスコープを設定します。
例を挙げましょう。私はあなたがそれを愛することを望みます:)
public class Main {
public static void main(String args[]) {
Java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager
.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (Exception ex) {
ex.printStackTrace();
}
new Ihm().setVisible(true);
}
});
}
}
私の構成Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("com.myproject.configuration")
@PropertySource("classpath:/application.properties")
public class Config {
@Bean
public Configurator configurator() {
return new Configurator();
}
}
私のJava私の構成Beanを使用するIHMをスイングします。
public class Ihm extends JFrame {
private MyConfiguration configuration;
public SmartRailServerConfigurationFileIhm() {
try {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
configurator = context.getBean(MyConfiguration.class);
} catch (Exception ex) {
}
System.out.println(configuration);
...
...
}
}
問題はここにあります:
frame.add(new NotesPanel()、BorderLayout.CENTER);
notepadクラスのコンストラクターでNotesPanelクラスの新しいオブジェクトを作成しています。
コンストラクタはメソッドmainの前に呼び出されるため、Springコンテキストはまだロードされていません。
NotesPanelのオブジェクトをインスタンス化する場合、その時点ではSpringコンテキストが存在しないため、BackgroundGrayを自動ワイヤリングできません。
Springで管理されているか、newで作成されているかに関係なく、任意のインスタンスでDIを実行できます。
これを行うには、次のコードを使用します...
AutowireCapableBeanFactory awcbf = applicationContext.getAutowireCapableBeanFactory();
awcbf.autowireBean(yourInstanceCreatedWithNew);
これは、元々Springなしで開発されたアプリケーションにSpringを導入するための優れた方法でもあります。これにより、アプリケーション内のすべてのクラスをSpring Beanに変換する必要なく、必要な場所でSpringを使用できます(通常、 (Spring BeanなしでSpring Beanを使用する)。