java - Spring 中的单例与 Autowired 字段

标签 java spring autowired applicationcontext

我面临着需要 Autowired 类的某个实例的问题。我有以下架构:

我的应用程序上下文:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
                        http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.2.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <context:annotation-config />

    <context:component-scan base-package="test.DELETEME"
        annotation-config="true" />

    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="true" />

    <bean id="mainGUI" class="test.DELETEME.MainWindow" />

</beans>

这里我注入(inject)应用程序上下文:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Singleton {

    /**
     * Application Context
     */
    private static ApplicationContext ctx;

    public static void main(String[] args) {
        ctx = new ClassPathXmlApplicationContext("applicationContext_Test.xml");
        MainWindow gui = ctx.getBean("mainGUI", MainWindow.class);
        gui.start();
    }   
}

此外,我正在将我的 GUI 连接在一起。

@Component
public class MainWindow extends JFrame {


    /**
     * UUID
     */
    private static final long serialVersionUID = -4931876787108249107L;

    public static JTabbedPane tabbedPane;

    @Autowired
    private static ResultsTabPanel resultsTabPanel; 

    /**
     * create the Layout
     * @throws Exception 
     */
    private void makeLayout() throws Exception {


        setLayout(new BorderLayout());

        createTabBar();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);

    }

    /**
     * create Tab Menu
     * @throws Exception 
     */
    public void createTabBar() throws Exception {

        tabbedPane = new JTabbedPane(JTabbedPane.TOP);

        /*
         * Main View 
         */
        tabbedPane.addTab("Main", new JPanel());
        tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);

        /*
         * Result table
         */
        tabbedPane.addTab("Results", resultsTabPanel.createLayout());
        tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);


        //Add the tabbed pane to this panel.
        add(tabbedPane);

        //The following line enables to use scrolling tabs.
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

    }

    /**
     * starts the GUI
     */
    public void start() {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    makeLayout();
                } catch (Exception e) {
                    e.printStackTrace();
                }   
            }
        });
    }

    public static JTabbedPane getInstance() {
        if(tabbedPane == null) {
            tabbedPane = new JTabbedPane();
        }
        return tabbedPane;
    }
}

我需要实例的类(class):

@Component
public class ResultsTabPanel extends JPanel{

    /**
     * UUID.
     */
    private static final long serialVersionUID = 5940818789959562707L;

    private static ResultsTabPanel instance;

    /**
     * Creates the Layout of the REA Tab.
     * @return
     */
    public JScrollPane createLayout() {
        JPanel panel = new JPanel(new MigLayout(""));
        JScrollPane sp;

        JLabel lab = new JLabel("Results");
        lab.setFont(new Font("Tahoma", Font.BOLD, 15));

        panel.add(lab, "wrap");

        sp = new JScrollPane(panel);
        sp.repaint();
        sp.validate();

        return sp;
    }

    public static ResultsTabPanel getInstance() {
        if(instance == null) {
            instance = new ResultsTabPanel();
        }
        return instance;
    }
}

但是,我收到错误:

1012 [main] WARN  org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor  - Autowired annotation is not supported on static fields: private static test.DELETEME.ResultsTabPanel test.DELETEME.MainWindow.resultsTabPanel
java.lang.NullPointerException
    at test.DELETEME.MainWindow.createTabBar(MainWindow.java:60)
    at test.DELETEME.MainWindow.makeLayout(MainWindow.java:36)
    at test.DELETEME.MainWindow.access$0(MainWindow.java:31)
    at test.DELETEME.MainWindow$1.run(MainWindow.java:79)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$400(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
com.passlogix.vgo.ho.WindowHandleException: null: test.DELETEME.MainWindow[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    at com.passlogix.vgo.ho.ApplicationWindow.nativeGetWindowHandle(Native Method)
    at com.passlogix.vgo.ho.ApplicationWindowAccessJava1dot4.getHWnd(ApplicationWindowAccessJava1dot4.java:50)
    at com.passlogix.vgo.ho.WindowScanner.run(WindowScanner.java:569)    

对于如何获取 ResultsTabPanel 实例或如何全局设置 ResultsTabPanel 有什么建议吗?

感谢您的回答!

最佳答案

正如错误消息所述:

Autowired annotation is not supported on static fields

因此您无法 Autowiring 静态依赖项。因此,您需要删除静态或创建一个非静态 setter ,您将从 Spring Autowiring resultsTabPane 并设置静态变量:

@Autowired
public void setResultsTabPanel (ResultsTabPanel resultsTabPane){
MainWindow.resultsTabPane = resultsTabPane;
}

关于java - Spring 中的单例与 Autowired 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27101780/

相关文章:

java - 在两个 Java 组件之间发送消息

java - actionPerformed(ActionEvent e) 方法中的对象是什么

java - Hibernate Envers 与 JBoss、Spring 和 Maven - 不写入审计记录

java - 使用 Jackson 的过滤器将树结构序列化为 JSON

java - 从 spring multiple <form :select> 绑定(bind)对象

java - Spring中如何从@Autowired List<>的每个bean中获取@Qualifier

java - Hibernate - FetchType.LAZY 急切地加载数据

java - OSGi/Equinox、声明式服务和延迟加载

java - 无法 Autowiring Spring 环境

java - Spring(-Boot) Autowiring 在裸初始化项目中始终为空