使用手动创建的bean连接xml bean时的NoSuchBeanDefinitionException

时间:2018-03-22 10:29:44

标签: java spring

我在 app-context.xml 文件中有以下bean定义:

deleteButton

我尝试通过代码手动创建addNewButton String[] contextPaths = new String[] {"todo/app-context.xml"}; ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(contextPaths); ActionListenerButton addNewButton = new ActionListenerButton(); addNewButton.setText("Add New"); System.out.println("setText(Add New)"); ListTableActionListener addActionListener = (ListTableActionListener) ctx.getBean("addNewButtonActionListener"); addNewButton.setActionListener(addActionListener); ActionListenerButton deleteButton = new ActionListenerButton(); deleteButton.setText("Delete"); System.out.println("setText(Delete)"); ActionListener deleteActionListener = (ActionListener) ctx.getBean("addNewButtonActionListener"); deleteButton.setActionListener(deleteActionListener); AutowireCapableBeanFactory factory = ctx.getAutowireCapableBeanFactory(); factory.autowireBean(addNewButton); factory.initializeBean(addNewButton, "addNewButton"); factory.autowireBean(deleteButton); factory.initializeBean(deleteButton, "deleteButton"); bean:

addNewButtonActionListener

addNewButtonActionListenerdeleteButtonaddNewButton@Component("addNewButtonActionListener") public class AddNewButtonActionListener extends ListTableActionListener { @Resource(name="itemList") public void setList(List list) { this.list = list; } @Resource(name="itemTable") public void setTable(JTable itemTable) { this.itemTable = itemTable; } public void actionPerformed(ActionEvent e) { list.add("New Item"); itemTable.revalidate(); } } bean依赖,使用注释定义:

@Component("deleteButtonActionListener")
public class DeleteButtonActionListener extends ListTableActionListener {

    @Resource(name="itemList")
    public void setList(List list) {
        this.list = list;
    }

    @Resource(name="itemTable")
    public void setTable(JTable itemTable) {
        this.itemTable = itemTable;
    }

    public void actionPerformed(ActionEvent e) {
        int selectedRow = itemTable.getSelectedRow(); 

        if (selectedRow == -1) {
            // if there is no selected row, don't do anything
            return;
        }

        if (itemTable.isEditing()) { 
            // if we are editing the table, don't do anything
            return;
        }

        if (selectedRow < list.size()) {
            list.remove(selectedRow);
            itemTable.revalidate(); 
        }        
    }
}
ActionListenerButton

public class ActionListenerButton extends JButton { String text; public String getText() { return text; } public void setText(String text) { this.text = text; } private ActionListener actionListener; public void setActionListener(ActionListener actionListener) { this.actionListener = actionListener; } public ActionListener getActionListener() { return actionListener; } public void init() { this.addActionListener(actionListener); } } 类看起来像这样:

buttonPanel

但似乎bean addNewButton(在xml中定义)是在deleteButtonNoSuchBeanDefinitionException bean之前创建的(应该由工厂,代码初始化),因为我得到了13:15:33.524 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.event.internalEventListenerFactory' 13:15:33.524 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.event.internalEventListenerFactory' to allow for resolving potential circular references 13:15:33.526 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.event.internalEventListenerFactory' 13:15:33.526 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mainFrame' 13:15:33.526 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'mainFrame' 13:15:33.543 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'mainFrame' to allow for resolving potential circular references 13:15:33.558 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mainPanel' 13:15:33.558 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'mainPanel' 13:15:33.563 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'mainPanel' to allow for resolving potential circular references 13:15:33.577 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'itemScrollPane' 13:15:33.577 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'itemScrollPane' 13:15:33.581 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'itemTable' 13:15:33.598 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'itemScrollPane' to allow for resolving potential circular references 13:15:33.604 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'itemScrollPane' 13:15:33.605 [main] WARN o.s.c.s.ClassPathXmlApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainFrame' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'mainPanel' while setting bean property 'mainPanel'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainPanel' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'buttonPanel' while setting bean property 'panelComponents' with key [1]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'deleteButton' available 13:15:33.605 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@77f99a05: defining beans [addNewButtonActionListener,deleteButtonActionListener,itemTableModel,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,mainFrame,mainPanel,itemScrollPane,itemTable,buttonPanel,itemList]; root of factory hierarchy 13:15:33.605 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Retrieved dependent beans for bean 'itemList': [addNewButtonActionListener, itemTableModel, deleteButtonActionListener] 13:15:33.606 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Retrieved dependent beans for bean 'itemTableModel': [itemTable] 13:15:33.606 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Retrieved dependent beans for bean 'itemTable': [deleteButtonActionListener, itemScrollPane] 13:15:33.606 [main] DEBUG o.s.b.f.s.DisposableBeanAdapter - Invoking destroy() on bean with name 'itemList' Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainFrame' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'mainPanel' while setting bean property 'mainPanel'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainPanel' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'buttonPanel' while setting bean property 'panelComponents' with key [1]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'deleteButton' available 包含描述&#34;没有名为&#39; deleteButton&#39;可用&#34;

deleteButton

如何让Spring在addNewButton bean之前实例化buttonPanel<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <context:component-scan base-package="todo"/> <bean id="mainFrame" class="todo.ui.MainFrame" init-method="init"> <property name="mainPanel"> <ref bean="mainPanel"/> </property> <property name="title"> <value>My To Do List</value> </property> </bean> <bean id="mainPanel" class="todo.ui.BoxLayoutPanel" init-method="init"> <property name="axis"> <!-- "1" corresponds to BoxLayout.Y_AXIS Spring can access constants, but it's more complex --> <value>1</value> </property> <property name="panelComponents"> <list> <ref bean="itemScrollPane"/> <ref bean="buttonPanel"/> </list> </property> </bean> <bean id="itemScrollPane" class="javax.swing.JScrollPane"> <constructor-arg> <ref bean="itemTable"/> </constructor-arg> </bean> <bean id="itemTable" class="javax.swing.JTable" depends-on="itemTableModel"> <property name="model"> <ref bean="itemTableModel"/> </property> </bean> <bean id="buttonPanel" class="todo.ui.BoxLayoutPanel" init-method="init" depends-on="deleteButton"> <property name="axis"> <!-- "0" corresponds to BoxLayout.X_AXIS --> <value>0</value> </property> <property name="panelComponents"> <list> <ref bean="deleteButton"/> <ref bean="addNewButton"/> </list> </property> </bean> <!-- <bean id="deleteButton" class="todo.ui.button.ActionListenerButton" init-method="init"> <property name="actionListener"> <ref bean="deleteButtonActionListener"/> </property> <property name="text"> <value>Delete</value> </property> </bean> --> <!-- <bean id="deleteButtonActionListener" class="todo.ui.button.DeleteButtonActionListener"> <property name="list"> <ref bean="itemList"/> </property> <property name="table"> <ref bean="itemTable"/> </property> </bean> --> <!-- <bean id="addNewButton" class="todo.ui.button.ActionListenerButton" init-method="init"> <property name="actionListener"> <ref bean="addNewButtonActionListener"/> </property> <property name="text"> <value>Add New</value> </property> </bean> --> <!-- <bean id="addNewButtonActionListener" class="todo.ui.button.AddNewButtonActionListener"> <property name="list"> <ref bean="itemList"/> </property> <property name="table"> <ref bean="itemTable"/> </property> </bean> --> <util:list id="itemList"> <value>Item 1</value> <value>Item 2</value> <value>Item 3</value> </util:list> </beans> bean?

P.S。完整 app-context.xml 现在看起来像这样:

AutowireCapableBeanFactory

UPD

或许我错了,我的代码lazy-init="true"并没有真正创建bean并将它们添加到Spring容器中...... 因为我在xml中将mainFrame属性添加到mainPanelbuttonPanelmainFrame bean,并在带有工厂的代码后调用了AutowireCapableBeanFactory factory = ctx.getAutowireCapableBeanFactory(); factory.autowireBean(addNewButton); factory.initializeBean(addNewButton, "addNewButton"); factory.autowireBean(deleteButton); factory.initializeBean(deleteButton, "deleteButton"); ctx.getBean("mainFrame");

14:04:49.780 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
14:04:49.783 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source
setText(Add New)
14:04:49.785 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'addNewButtonActionListener'
setText(Delete)
14:04:49.786 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'deleteButtonActionListener'
14:04:49.812 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mainFrame'
14:04:49.812 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'mainFrame'
14:04:49.828 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'mainFrame' to allow for resolving potential circular references
14:04:49.846 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mainPanel'
14:04:49.846 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'mainPanel'
14:04:49.850 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'mainPanel' to allow for resolving potential circular references
14:04:49.869 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'itemScrollPane'
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainFrame' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'mainPanel' while setting bean property 'mainPanel'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainPanel' defined in class path resource [todo/app-context.xml]: Cannot resolve reference to bean 'buttonPanel' while setting bean property 'panelComponents' with key [1]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'deleteButton' available

我在控制台中获得以下输出:

addNewButtonActionListener

即,Spring只返回单例bean deleteButtonActionListeneraddNewButton的缓存实例,bot不会创建并返回bean deleteButton<?php $servername = '10.4.41.164:3306'; $username = 'admin'; $password = 'admin'; $db = 'AssistMe'; echo "Pepito"; // Create connection $conn = mysqli_connect($servername, $username, $password); if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } else { echo "Connected succesfully"; } ?> 的实例。< / p>

1 个答案:

答案 0 :(得分:0)

我在related SO question找到了答案。更改代码后:

AutowireCapableBeanFactory factory = ctx.getAutowireCapableBeanFactory();

BeanDefinition definition = new RootBeanDefinition(ActionListenerButton.class);
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.registerBeanDefinition("addNewButton", definition);
registry.registerBeanDefinition("deleteButton", definition);
factory.initializeBean(addNewButton, "addNewButton");
factory.initializeBean(deleteButton, "deleteButton");

应用程序已成功启动。