Java 如何在用new创建的对象中自动装配弹簧中的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25284011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to autowire an object in spring in an object created with new
提问by user1119859
all I want to do is autowire the field backgroundGray in the NotesPanel class, but all I get is the exception below.
我想要做的就是在 NotesPanel 类中自动装配字段 backgroundGray,但我得到的只是下面的异常。
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:
<?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>
采纳答案by Ralph
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
.
Spring 支持@Autowire
,...仅适用于 Spring Bean。通常,Java 类在由 Spring 创建时成为 Spring Bean,而不是由new
.
One workarround is to annotate the class with @Configurable
but you must use AspectJ (compile time or loadtime waving)!
一种解决方法是@Configurable
使用 AspectJ注释类,但您必须使用 AspectJ(编译时或加载时波动)!
@see Using Spring's @Configurable
in three easy stepsfor an short step by step instruction.
@see以三个简单的步骤使用 Spring 的@Configurable
简短分步说明。
回答by Xstian
When you create an object by new, autowire\inject don't work...
当您通过 new 创建对象时,autowire\inject 不起作用...
as workaround you can try this:
作为解决方法,你可以试试这个:
create your template bean of NotesPanel
创建您的 NotesPanel 模板 bean
<bean id="notesPanel" class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
and create an istance in this way
并以这种方式创建一个istance
context.getBean("notesPanel");
PROTOTYPE: This scopes a single bean definition to have any number of object instances.
PROTOTYPE:这将单个 bean 定义范围限定为具有任意数量的对象实例。
回答by Alfonso Pinto
The problem is here:
问题在这里:
frame.add(new NotesPanel(), BorderLayout.CENTER);
frame.add(new NotesPanel(), BorderLayout.CENTER);
you are creating a new object for class NotesPanel in the constructor of class Notepad.
您正在 Notepad 类的构造函数中为类 NotesPanel 创建一个新对象。
The constructor is called before method main, so Spring context has not been loaded yet.
构造函数在方法 main 之前被调用,因此 Spring 上下文尚未加载。
When instantiating the object for NotesPanel, it can't auto wire BackgroundGray because Spring context doesn't exists at that moment.
在为 NotesPanel 实例化对象时,它无法自动连接 BackgroundGray,因为此时 Spring 上下文不存在。
回答by Aron Elias Herrera Ponte
I share with you an example. I hope you love it :)
我和你分享一个例子。我希望你喜欢它:)
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);
}
});
}
}
My configuration bean:
我的配置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();
}
}
My java swing ihm that uses my configuration bean:
我的 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);
...
...
}
}
回答by Rodney P. Barbati
You can perform DI on any instance, whether Spring managed or created with new.
您可以在任何实例上执行 DI,无论是 Spring 管理的还是使用 new 创建的。
To do so, use the following code...
为此,请使用以下代码...
AutowireCapableBeanFactory awcbf = applicationContext.getAutowireCapableBeanFactory();
awcbf.autowireBean(yourInstanceCreatedWithNew);
This is also a great way to introduce Spring into an application that was developed originally without Spring - as it allows you to use Spring where you want it without having to convert every class in the application into a Spring bean (because typically, you can't use a Spring bean without a Spring bean).
这也是将 Spring 引入最初没有 Spring 开发的应用程序的好方法 - 因为它允许您在需要的地方使用 Spring,而不必将应用程序中的每个类都转换为 Spring bean(因为通常情况下,您可以' t 使用没有 Spring bean 的 Spring bean)。