【问题标题】:GenericXmlApplicationContext vs ClassPathXmlApplicationContextGenericXmlApplicationContext 与 ClassPathXmlApplicationContext
【发布时间】:2020-08-08 08:39:13
【问题描述】:

我有以下配置:

1.parent-ctx.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"
    xmlns:c="http://www.springframework.org/schema/c"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="Bean1InParent" class="java.lang.String">
        <constructor-arg>
            <value>Bean in Parent App Context</value>
        </constructor-arg>
    </bean>

</beans>
  1. child-ctx.xml

     <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:c="http://www.springframework.org/schema/c"
         xmlns:p="http://www.springframework.org/schema/p"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
         <bean class="com.app.appcontext.hierarchy.MyClass" id="myclass">
             <property name="value">
                 <ref parent="Bean1InParent" />
             </property>
         </bean>
    
     </beans>
    

以下是com.app.appcontext.hierarchy.MyClass包中的类:

public class MyClass {


    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

主类是有效的:

import org.springframework.context.support.GenericXmlApplicationContext;

public class AppCtxHierarchyMain {

    public static void main(String[] args) {
        GenericXmlApplicationContext parent = new GenericXmlApplicationContext();
        parent.load("classpath:parent-ctx.xml");
        parent.refresh();
        GenericXmlApplicationContext child = new GenericXmlApplicationContext();
        child.load("classpath:child-ctx.xml");

        child.setParent(parent);

        child.refresh();

        MyClass cls = child.getBean("myclass", MyClass.class);

        System.out.println(cls.getValue());
        
        child.close();

    }

}

另一个不起作用的主类代码:

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppCtxHierarchyMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("parent-ctx.xml");
        ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext("child-ctx.xml");

        child.setParent(parent);

        child.refresh();

        MyClass cls = child.getBean("myClass", MyClass.class);

        System.out.println(cls.getValue());
        
        child.close();

    }

}

我对不起作用的代码很好奇。这里有什么区别?

附: : 春季版 3.2.9

这里发生了异常:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myclass' defined in class path resource [child-ctx.xml]: Cannot resolve reference to bean 'Bean1InParent' while setting bean property 'value'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'Bean1InParent' is defined
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:326)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.airtel.appcontext.hierarchy.AppCtxHierarchyMain.main(AppCtxHierarchyMain.java:9)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'Bean1InParent' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1114)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:279)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:320)

【问题讨论】:

  • 尝试使用另一个构造函数 ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent)。
  • @OleksiiMLD :是的,我已经尝试过并且效果很好,但是有什么特定的代码不起作用
  • 不工作意味着您有异常或找不到bean。构造函数 ClassPathXmlApplicationContext 将自动刷新上下文,子 bean 定义应该失败,因为找不到父对象
  • @CyrilG。我已经把异常跟踪
  • 好吧,原因是我在之前的评论中解释的:缺少 Bean1InParent 因为子上下文在设置父上下文之前被刷新。

标签: java spring applicationcontext


【解决方案1】:

找不到 bean,因为 ClassPathXmlApplicationContext 将在设置父上下文之前刷新子上下文。然后 bean 创建将失败,因为缺少 Bean1InParent。您需要在子上下文的构造函数中传递父上下文。

public class AppCtxHierarchyMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("parent-ctx.xml");
        ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext("child-ctx.xml", parent );

        MyClass cls = child.getBean("myClass", MyClass.class);
        System.out.println(cls.getValue());
    
    ...

    }

}

编辑:

您也可以在创建子上下文时使用带有参数 refresh 为 false 的构造函数

ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(new String[] {"child-ctx.xml"}, false);

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2016-10-01
    相关资源
    最近更新 更多