user1119859 user1119859 - 3 months ago 6
Java Question

How to autowire an object in spring in an object created with new

all I want to do is autowire the field backgroundGray in the NotesPanel class, but all I get is the exception below.

So, question is, how to autowire it correctly ? It really drives me crazy because it's probably something very stupid I'm doing wrong...

thanks for any help!
Thorsten

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)


Class Notepad:

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

}
}


Class Notespanel:

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

}


Class 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>

Answer

Spring support @Autowire, ... only for Spring Beans. Normally a Java Class become a Spring Bean when it is created by Spring, but not by new.

One workarround is to annotate the class with @Configurable but you must use AspectJ (compile time or loadtime waving)!

@see Using Spring's @Configurable in three easy steps for an short step by step instruction.