Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 596
user1119859 Avatar asked Aug 13 '14 10:08

user1119859


People also ask

Does spring Autowire create new instance?

When you autowire a prototype bean, Spring will initialize a new instance of the bean. If you autowire the bean in multiple places, then Spring will create a new instance for every place you autowire the bean.

What is difference between Autowired and new object creation?

Well, the main difference is that in case u use @Autowired the object is also created, however, it's created by container and container decide when to do that. I want to give you a simple example: You have four classes 1,2,3 and 4.

Can we use @autowired in pojo?

The beans can be wired via constructor or properties or setter method. For example, there are two POJO classes Customer and Person. The Customer class has a dependency on the Person. @Autowired annotation is optional for constructor based injection.

Can you Autowire byType when more than one bean with the same type exists?

Autowiring using property type. Allows a property to be autowired if exactly one bean of property type exists in the container. If more than one exists, it's a fatal exception is thrown, which indicates that you may not used byType autowiring for that bean.


2 Answers

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.

like image 141
Ralph Avatar answered Oct 04 '22 16:10

Ralph


When you create an object by new, autowire\inject don't work...

as workaround you can try this:

create your template bean of NotesPanel

<bean id="notesPanel" class="..." scope="prototype">
    <!-- collaborators and configuration for this bean go here -->
</bean>

and create an istance in this way

context.getBean("notesPanel");

PROTOTYPE : This scopes a single bean definition to have any number of object instances.

like image 25
Xstian Avatar answered Oct 04 '22 15:10

Xstian