原型Bean中的自动装配

时间:2014-01-04 23:44:04

标签: java spring swing

我正在使用Swing with Spring创建一个财务应用程序。在我的应用程序的一部分中,我有一个JList,其中包含应用程序中每个JLabel的{​​{1}}。点击Account后,我想在JLabel中显示JPanel类型AccountTab。这都在以下控制器中执行。

JTabbedPane

每个@Component public class AccountListController extends MouseAdapter implements MouseListener { @Autowired private AccountService accountService; @Autowired private MainFrameView mainFrameView; @Autowired private ApplicationContext context; @Override public void mouseClicked(MouseEvent e) { if (e.getSource() instanceof JList) { JList list = (JList) e.getSource(); JTabbedPane tabbedPane = this.mainFrameView.getTabbedPane(); SidebarItem item = (SidebarItem) list.getModel().getElementAt(list.getSelectedIndex()); Account account = accountService.findById(item.getValue()); if (tabbedPane.indexOfTab(account.getName()) == -1) { AccountTab panel = context.getBean(AccountTab.class); panel.addTransactions(account.getTransactions()); panel.getSplitPane().setDividerLocation(500); tabbedPane.addTab(item.getTitle(), panel); } tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(account.getName())); } } } 点击AccountTab更改,因此我将JLabel设为原型bean,因此我收到了每个帐户的新实例。为了使原型范围有效,我需要使用AccountTab。这是context.getBean(AccountTab.class)代码:

AccountTab

您会注意到我尝试自动装配类型为@Component @Scope("prototype") public class AccountTab extends JPanel { @Autowired private AccountTransactionPane transactionPane; private static final long serialVersionUID = 1L; private JTable table = new JTable(); private JSplitPane splitPane; public AccountTab() { this.setLayout(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(this.table); splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane); splitPane.setEnabled(false); this.add(splitPane, BorderLayout.CENTER); } public void addTransactions(List<AccountTransaction> transactions) { this.table.setModel(new AccountTransactionTableModel(transactions)); } //omitted rest of code } 的bean,但是,bean没有正确自动装配,它为空。以下是AccountTransactionPane的代码:

AccountTransactionPane

我有一个具体问题和一个一般问题。首先,@Component public class AccountTransactionPane extends JPanel { private static final long serialVersionUID = 1L; JTabbedPane tabbedPane = new JTabbedPane(); private JPanel withdrawlTransactionPane = new DepositTransactionPane().build(); private JPanel depositTransactionPane = new DepositTransactionPane().build(); private JPanel transferTransactionPane = new DepositTransactionPane().build(); public AccountTransactionPane() { this.setLayout(new BorderLayout()); tabbedPane.addTab("Withdrawl", this.withdrawlTransactionPane); tabbedPane.addTab("Deposit", this.depositTransactionPane); tabbedPane.addTab("Transfer", this.transferTransactionPane); this.add(tabbedPane, BorderLayout.CENTER); } //rest of class omitted } 未在AccountTransactionPane bean中自动装配。我不知道为什么,如何在AccountTab内自动装配AccountTransactionPane bean?

我的第二个问题更为笼统,我正在自动装配一切。好像一切都需要成为一个豆子。我已经陷入了创建控制器(bean)的模式,注入UI(bean),然后注入另一个用作监听器的控制器(bean),在该控制器中我注入一个服务(bean)。这是正常的吗?我找不到任何有关Swing Spring应用程序的好例子来指导我。

更新:Spring Java Config

AccountTab

2 个答案:

答案 0 :(得分:1)

注射过程就像这样

  • 获取该类的Class实例以创建
  • 的bean
  • 获取Constructor或使用Class#newInstance()创建bean
  • 使用所有@Autowired目标注入bean。

你的类'构造函数就像

@Autowired
private AccountTransactionPane transactionPane;

...

public AccountTab() {
    this.setLayout(new BorderLayout());
    JScrollPane scrollPane = new JScrollPane(this.table);
    splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane);
    splitPane.setEnabled(false);
    this.add(splitPane, BorderLayout.CENTER);
}

显然transactionPane在构造函数中将是null。 Spring还没有注射它。如果您需要对注入的bean进行一些初始化,请考虑使用@PostConstruct带注释的方法。


  

我的第二个问题更为笼统,我正在自动装配一切。它   好像一切都需要成为一个豆子。我陷入了困境   模式创建一个控制器(bean),注入UI(bean),然后注入   另一个用作监听器的控制器(bean)   controller我注入了一个服务(bean)。这是正常的吗?

应用程序应该有一个加载Spring ApplicationContext的入口点。每个其他组件(及其依赖项)都应由ApplicationContext管理。

答案 1 :(得分:1)

使用 init 方法构建面板而不是Ctor。自动装配在施工后完成。

即:

@PostConstruct
public void init() {
  this.setLayout(new BorderLayout());
  JScrollPane scrollPane = new JScrollPane(this.table);
  splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane);
  splitPane.setEnabled(false);
  this.add(splitPane, BorderLayout.CENTER);
}

您还可以在Ctor中注入transactionPane:

   @Autowired 
   public AccountTab(AccountTransactionPane transactionPane) {
     ...
}