Как автоувеличивать объект в 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).