当前位置: 首页 > 知识库问答 >
问题:

原型Bean中的自动连接

鲁鸿朗
2023-03-14

我正在使用Swing和Spring创建一个金融应用程序。在应用程序的一部分中,我有一个JList,其中包含应用程序中每个帐户JLabel。单击JLabel时,我希望在JTabedPane中显示AccountTab类型的JPanel。这都是在下面的控制器中执行的。

@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点击更改,因此我将AccountTab设置为一个原型bean,因此我将为每个帐户接收一个新实例。为了使原型作用域工作,我需要使用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
}

您将注意到我试图自动连接AccountTransactionPane类型的bean。但是,该bean没有正确地自动连接,它是空的。以下是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
}

我有一个具体的问题和一个一般的问题。首先,AccountTransactionPaneAccountTabbean中没有自动连接。我不知道为什么,如何让AccountTransactionPanebean自动连接到AccountTab中?

我的第二个问题是比较普遍的,我正在自动控制所有的东西。似乎每件事都需要一颗豆子。我陷入了这样的模式:创建一个控制器(bean),注入UI(bean),然后注入另一个用作监听器的控制器(bean),在该控制器中注入一个服务(bean)。这正常吗?我找不到任何有Spring应用程序的大型摆动的好例子来指导我。

更新:Spring Java Config

@Configuration
@EnableJpaRepositories(basePackages="rhcloud.blog.tothought.data.repositories")
@EnableTransactionManagement
@ComponentScan({"rhcloud.blog.tothought.data", "rhcloud.blog.tothought.controllers", "rhcloud.blog.tothought.view.ui"})
public class ApplicationConfiguration {

      private static final String H2_JDBC_URL_TEMPLATE = "html" target="_blank">jdbc:h2:file:~/MyFinances/data;TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3";

      @Bean
      public DataSource dataSource(){
            JdbcDataSource ds = new JdbcDataSource();       
            ds.setURL(H2_JDBC_URL_TEMPLATE);
            ds.setUser("sa");
            ds.setPassword("sa");

            return ds;
      }

      @Bean
      public EntityManagerFactory entityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setShowSql(true);
        vendorAdapter.setDatabase(Database.H2);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("rhcloud.blog.tothought.data.entities");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();

        return factory.getObject();
      }

      @Bean
      public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
      }

      /**
       * See: http://stackoverflow.com/questions/8434712/no-persistence-exception-translators-found-in-bean-factory-cannot-perform-excep
       * @return
       */
      @Bean 
        public HibernateExceptionTranslator hibernateExceptionTranslator(){ 
          return new HibernateExceptionTranslator(); 
        }

      @Bean
      public Application application(){
          return new Application();
      }
}

共有1个答案

诸经略
2023-03-14

注射过程是这样的

  • 获取类的class实例,为其创建bean
  • 获取构造函数或使用类#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);
}

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

 类似资料:
  • 我正在使用一些现有的代码,它正在做我以前没有见过的事情。我已经处理了使用方法注入将原型bean自动转换为单例,或者使用getBean()从上下文中获取bean。我在这段代码中看到的是一个bean,它是一个原型,使用getBean()检索,它具有自动连接的依赖关系。这些大部分都是单例bean,这是有道理的。但是有另一个原型bean的自动生成,从我所看到的情况来看,它似乎得到了一个新的bean。我的问

  • 我是Spring的新手。我正面临Spring-Boot的问题。我正在尝试将外部配置文件中的字段自动装配到自动装配的bean中。我有以下类 应用程序。Java语言 AppConfig。Java语言 服务接口 服务1 我无法在App类的postconstruct方法中显示服务名称变量。我这样做对吗?

  • 我通过Spring Boot 1.1.8使用Spring 4,并创建了一个类来缓存一些数据。这个类依赖于泛型来工作,但我在Spring和将这个类自动连接为另一个服务中的bean方面遇到了问题。 我会遇到如下错误: 所涉及的班级: 类BaseRepository扩展JpaRepository如下。其他实际存储库扩展了这个。 BaseWithName类是一个MappedSuperclass,它定义名称

  • 问题内容: 我试图将一个bean 注入一个bean中,以便对单例bean方法的每个新调用都具有原型bean的新实例。 考虑如下的单例豆: 我希望每次调用该方法时,都会使用一个新实例。 下面是原型bean: 似乎正在发生的事情是,Spring急于在该方法中交付PrototypeBean的新实例。也就是说,该方法中的两行代码将在每一行中创建一个prototypeBean的新实例。 因此,在第二行中,输

  • Spring具有bean类型/作用域,如 -singleton bean(每个应用程序上下文只有一个bean), -prototype bean(每个请求一个新bean) 现在,如果在单例bean中有对原型bean的引用,是否有办法在对单例bean的每个请求中获得一个新的原型bean(在单例bean中)。< br >如果是,配置会是什么样的?

  • 我不确定我的代码出了什么问题。我正在学习弹簧靴。但我无法运行应用程序,因为我得到以下错误 模型类 主类: