Как автоувеличивать объект в spring в объекте, созданном с помощью нового
все, что я хочу сделать, это autowire field backgroundGray в классе NotesPanel, но все, что я получаю, является исключением ниже.
Итак, вопрос в том, как правильно его автоувертировать? Это действительно сводит меня с ума, потому что, наверное, что-то очень глупое я делаю неправильно...
спасибо за любую помощь!
Торстен
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>
Ответы
Ответ 1
Spring поддержка @Autowire
,... только для Spring Beans. Обычно класс Java становится Spring Bean, когда он создается Spring, но не new
.
Один рабочий стол состоит в том, чтобы аннотировать класс с помощью @Configurable
, но вы должны использовать AspectJ (время компиляции или размахивание времени загрузки)!
@see Используя Spring @Configurable
за три простых шага за короткую пошаговую инструкцию.
Ответ 2
Когда вы создаете объект по-новому, autowire\inject не работает...
в качестве обходного пути вы можете попробовать следующее:
создайте свой шаблон bean NotesPanel
<bean id="notesPanel" class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
и создайте это таким образом
context.getBean("notesPanel");
PROTOTYPE. Это позволяет определить одно определение bean для любого количества экземпляров объектов.
Ответ 3
Проблема здесь:
frame.add(новый NotesPanel(), BorderLayout.CENTER);
вы создаете новый объект для класса NotesPanel в конструкторе класса Notepad.
Конструктор вызывается перед main, поэтому Spring контекст еще не загружен.
При создании объекта для NotesPanel он не может автоматически проецировать BackgroundGray, потому что в данный момент контекст Spring не существует.
Ответ 4
Я рассказываю вам пример.
Надеюсь, вам это понравится:)
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 swing ihm, который использует мою конфигурацию bean:
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);
...
...
}
}
Ответ 5
Вы можете выполнить DI для любого экземпляра, независимо от того, управляется ли Spring или создается с новым.
Для этого используйте следующий код...
AutowireCapableBeanFactory awcbf = applicationContext.getAutowireCapableBeanFactory();
awcbf.autowireBean(yourInstanceCreatedWithNew);
Это также отличный способ представить Spring в приложении, которое изначально разрабатывалось без Spring - поскольку оно позволяет вам использовать Spring там, где вам это нужно, без необходимости превращать каждый класс в приложении в bean-компонент Spring (поскольку обычно нельзя использовать Spring Bean без Spring Bean).