首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring在继承时创建两次子bean,并且从不创建父bean

在Spring框架中,如果在继承关系中子bean被创建了两次,而父bean从未被创建,这通常是由于配置错误或者Bean定义的冲突导致的。下面我将详细解释这个问题的基础概念,可能的原因,以及解决方案。

基础概念

在Spring中,bean的继承允许子bean继承父bean的属性。这种机制可以通过XML配置文件或者使用注解来实现。当一个bean继承另一个bean时,它可以使用父bean的配置作为基础,并且可以覆盖或添加新的配置。

可能的原因

  1. Bean定义重复:可能在不同的配置文件中重复定义了相同的子bean,导致Spring容器创建了两个实例。
  2. 组件扫描冲突:如果使用了组件扫描(@ComponentScan),并且子bean在多个包中被扫描到,可能会导致创建多个实例。
  3. 配置错误:可能在配置文件中错误地指定了bean的继承关系,导致Spring无法正确识别父bean。
  4. 作用域问题:如果子bean的作用域设置为prototype,每次请求都会创建一个新的实例。如果父bean的作用域为singleton,则只会创建一次。

解决方案

1. 检查Bean定义

确保子bean没有在多个地方被定义。例如,如果你使用XML配置,检查是否有多个<bean>元素定义了相同的子bean。

代码语言:txt
复制
<!-- 错误的示例 -->
<bean id="childBean" class="com.example.ChildBean" parent="parentBean"/>
<bean id="childBean" class="com.example.ChildBean" parent="parentBean"/> <!-- 重复定义 -->

2. 使用@ComponentScan注解

如果你使用注解配置,确保@ComponentScan没有扫描到重复的bean。

代码语言:txt
复制
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

确保com.example包中没有重复的子bean类。

3. 正确配置继承关系

确保在配置文件中正确指定了bean的继承关系。

代码语言:txt
复制
<bean id="parentBean" class="com.example.ParentBean"/>
<bean id="childBean" class="com.example.ChildBean" parent="parentBean"/>

4. 检查作用域

如果子bean的作用域设置为prototype,确保这是预期的行为。如果不是,可以将其更改为singleton

代码语言:txt
复制
@Component
@Scope("singleton")
public class ChildBean extends ParentBean {
}

示例代码

以下是一个简单的Java配置示例,展示了如何正确配置bean的继承关系:

代码语言:txt
复制
@Configuration
public class AppConfig {

    @Bean
    public ParentBean parentBean() {
        return new ParentBean();
    }

    @Bean
    public ChildBean childBean() {
        return new ChildBean(parentBean());
    }
}

public class ParentBean {
    // 父bean的属性和方法
}

public class ChildBean extends ParentBean {
    public ChildBean(ParentBean parentBean) {
        // 初始化子bean,可以使用父bean的实例
    }
    // 子bean的属性和方法
}

通过以上步骤,你应该能够解决Spring在继承时创建两次子bean,并且从不创建父bean的问题。如果问题仍然存在,建议检查日志和配置文件,以确定具体的冲突来源。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Spring 手动创建 bean 的两种方式

4.1 BeanDefinition BeanDefinition 是一个在 spring-context 包中的接口,他继承自两个接口: BeanMetadataElement:该接口只有一个方法...除了上述两个接口的方法,在 BeanDefinition 中,定义了一系列 Bean 属性,包括是否是单例,是否是抽象 bean,bean 的类型,配置获取该 bean 的 BeanFactory 名称等...时传递的 properties,我们只要将他们一一添加到 propertyValues 对象,并且赋值给 BeanDefinition 对象即可。...比如,如果我们使用 Spring 提供的 ApplicationContext.getBeansOfType() 方法来获取指定类型的 bean 时,spring 会尝试将所有该类型的 bean 全部实例化后返回回来...当我们执行 ApplicationContext.getBeansOfType() 时,Spring 回去寻找上下文中所有匹配参数类型的 bean,但如果 bean 需要被工厂方法创建,那么,Spring

2.7K30
  • 「Spring认证」Spring Bean 定义继承

    Spring Bean定义继承与Java类继承无关,但是继承的概念是一样的。您可以将父 bean 定义定义为模板,其他子 bean 可以从父 bean 继承所需的配置。...例子 让我们有一个工作的 Eclipse IDE 并采取以下步骤来创建一个 Spring 应用程序 - 以下是配置文件beans.xml中,我们定义的“HelloWorld”豆它有两个属性MESSAGE1...如果您的应用程序一切正常,它将打印以下消息 - 如果您在这里观察到,我们在创建“helloIndia”bean 时没有传递 message2,但是由于 Bean 定义继承,它通过了。...在定义 Bean 定义模板时,您不应指定class属性,而应指定抽象 属性,并应指定值为true的抽象属性,如下面的代码片段所示 - 父 bean 不能单独实例化,因为它是不完整的,并且它也被显式标记为...当定义像这样抽象时,它只能用作纯模板 bean 定义,用作子定义的父定义。

    61200

    Spring高手之路12——BeanDefinitionRegistry与BeanDefinition合并解析

    如果没有BeanDefinitionRegistry集中处理这些定义,那么Spring在尝试初始化sampleBean时可能会遭遇混淆,比如Spring尝试创建ServiceA的实例并为它注入sampleBean...如果没有这个BeanDefinitionRegistry,Spring在执行Bean的延迟加载或根据作用域创建Bean时,需要重新解析原始的配置资源,这增加了处理时间并可能导致潜在的配置错误。...当使用bean>元素在XML中定义bean时,通常会为该bean创建一个GenericBeanDefinition实例。...由于子Bean的BeanDefinition与父Bean的BeanDefinition已合并,所以能看到一个完整的属性集,这里在propertyValues中看到两个属性键值对:commonProperty...如果从XML配置中读取的Bean之间存在父子关系,这时会进行合并,合并后的BeanDefinition确保子Bean继承了父Bean的所有属性,并且能够覆盖它们。

    73550

    【小家Spring】BeanFactory体系和ApplicationContext体系,两大体系各接口分析、区别和联系

    :BeanFactory需要手动注册,而ApplicationContext则是自动注册 两者装载bean的区别 BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化...并且会调用其所有注册的post processor. // beanName表示在Bean定义中的名称。...; //bean创建状态控制.在解决循环依赖时有使用 设置一个Bean是否正在创建 void setCurrentlyInCreation(String beanName, boolean...在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现 ApplicationContext接口继承众多接口,集众多接口功能与一身,为Spring...//和其他在每次refresh时都创建一个新的内部BeanFactory实例的ApplicationContext实例不同 //本类中的BeanFactory从一开始就创建好并可在其中注册bean definitions

    1.9K41

    Spring的底层源码分析

    Spring运行原理 流程介绍 Spring 启动时读取应用程序提供的Bean 配置信息,并在Spring 容器中生成一份相应的Bean 配置注册表,然后根据这张注册表实例化Bean,装配好Bean 之间的依赖关系...Spring 中有两个主要的容器系列 1)实现BeanFactory 接口的简单容器; 2)实现ApplicationContext 接口的高级容器。 点击查看这两个IOC容器的区别 1....ApplicationContext 在应用这个DefaultListableBeanFactory 对象的基础上,不仅实现了 BeanFactory 接口提供的功能方法,并且黏合了一些面向应用的功能...例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个Bean 有可能有父...ApplicationContext 创建时 ,继承的所有父类 public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory

    76920

    Spring的bean创建实例详解

    ,然后在创建SuperMarket对象时,向其构造函数传入了先前创建的Milk和Apple对象。...继承 bean的类之间具有继承关系 对于具有继承关系的bean,由于父类的属性,子类也会有,因而如果直接配置,那么两个bean的配置将会有很大一部分趋于相似。...,父类bean只需要按照正常方式声明即可,子类的bean只需要使用parent节点指定其继承的父类bean,并且指明子类与父类有差异的属性bean。...提取公共bean并进行继承 对于两个或多个bean,如果其大部分属性bean都是相似的,只有少部分不一致,那么就可以将公共的bean提取出来作为父bean,然后每个bean继承自这个bean...Outlet中drink属性的注入提取出来,从而形成一个父bean,即superSales,而SuperMarket和Outlet的bean只需要继承父bean,并且注入各自特有的bean即可。

    2.4K40

    Spring底层架构源码解析(二)

    lazyInit:表示Bean是否是懒加载 initMethodName:表示Bean初始化时要执行的方法 destroyMethodName:表示Bean销毁时要执行的方法 在...spring中,我们创建一个Bean时有两类方式(声明式方式,编程类方式),而在声明式方式中又有以下几种方式: 1.使用xml方式:bean/> 2.使用注解方式@Bean,@Component(@Service...在Spring的源码实现中,当我们new一个ApplicationContext时,其底层会new一个BeanFactory出 来,当使用ApplicationContext的某些方法时,比如getBean...在spring的源码中,有一个叫做DefaultListableBeanFactory的实现类,DefaultListableBeanFactory有很多很实用的功能,并且DefaultListableBeanFactory...AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持 在创建Bean的过程中能对Bean进行自动装配 12.

    7510

    Spring系列之bean的使用

    子类 Bean 会继承父类 Bean 的所有属性,子类 Bean 也可以覆盖父类 Bean 的属性。注意:子类 Bean 和父类 Bean 是同一个 Java 类。...它表示这个 Bean 将不会被实例化,一般用于父类 Bean,因为父类 Bean 主要是供子类 Bean 继承使用。...二、实例化Bean的三种方式 1.使用构造器实例化Bean 这是最简单的方式,Spring IOC容器即能使用默认空构造器也能使用有参数构造器两种方式创建Bean。...换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。...在默认情况下,spring容器在启动时不实例化prototype的Bean。此外,spring容器将prototype的Bean交给调用者后,就不再管理它的生命周期。

    62010

    赢了!美的一面,被我狠狠拿捏了

    第三种:通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题。 只有【第三种方式】的循环依赖问题被 Spring 解决了,其他两种方式在遇到循环依赖问题时,Spring都会产生异常。...三级缓存指的是 Spring 在创建 Bean 的过程中,通过三级缓存来缓存正在创建的 Bean,以及已经创建完成的 Bean 实例。...具体步骤如下: 实例化 Bean:Spring 在实例化 Bean 时,会先创建一个空的 Bean 对象,并将其放入一级缓存中。...通过三级缓存的机制,Spring 能够在处理循环依赖时,确保及时暴露正在创建的 Bean 对象,并能够正确地注入已经初始化的 Bean 实例,从而解决循环依赖问题,保证应用程序的正常运行。...每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都有两个指针,分别指向下一个叶子节点和上一个叶子节点,形成一个双向链表。

    6010

    两篇 Spring 总结(一)

    轻量级,Spring 是非侵入的,即使用的时候不需要实现任何接口或继承任何父类 面向切面编程(AOP)、依赖注入(DI) 容器,Spring 是一个容器,因为他包含并管理应用对象的生命周期 框架,Spring...Bean 的继承 Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean....继承这个父 Bean 的 Bean 称为子 Bean 子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置 子 Bean 也可以覆盖从父 Bean 继承过来的配置 父 Bean 可以作为配置模板...若只想把父 Bean 作为模板, 可以设置 bean> 的 abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean bean> 元素里的所有属性不是全会被继承....使用外部属性文件 在配置文件中配置 Bean 时,需要在 Bean 的配置里混入系统部署细节的信息,例如数据库连接信息,这些部署细节需要和 Bean 配置分离; Spring 提供了 BeanFactory

    77930

    Spring系列第13篇:使用继承简化bean配置(abstract & parent)

    来创建上面3个类对应的bean。...和serviceA两个属性,并且2个属性的值也是一样的,我们可以将上面的公共的代码抽取出来,通过spring中继承的方式来做到代码重用。...bean在spring容器中不会被创建,只是会将其当做bean定义的模板,而serviceB和serviceC的定义中多了一个属性parent,用来指定当前bean的父bean名称,此处是baseService...总结 bean元素的abstract属性为true的时候可以定义某个bean为一个抽象的bean,相当于定义了一个bean模板,spring容器并不会创建这个bean,从容器中查找abstract为true...的bean的时候,会报错BeanIsAbstractException异常 bean元素的parent属性可以指定当前bean的父bean,子bean可以继承父bean中配置信息,也可以自定义配置信息,

    49430

    Spring BeanDefinition 也分父子?

    BeanDefinition 的 parentName 属性的主要功能是允许我们在创建一个 bean 的同时,能够继承另一个已经定义好的 bean。...当我们需要创建多个相似的 bean 时,可以通过定义一个基础 bean,并在其他 bean 中使用 parentName 属性来继承其配置。...综上所述,Spring 框架中的 BeanDefinition 的 parentName 属性允许我们在定义 bean 时建立父子关系,从而提高代码的可维护性和重用性。...语法和用法:在 Java 中,继承是通过使用关键字 extends 来实现的,子类通过继承父类来获得父类的属性和方法。...而在 Spring 中,通过在 BeanDefinition 中配置 parentName 属性来指定一个 bean 的父 bean,从而继承父 bean 的配置。

    19420

    Spring技术知识点总结之七——Spring的设计模式

    Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是在传入参数后创建,还是传入参数前创建,这个要根据具体情况来定。...通过Spring接口的暴露,在实例化bean的阶段我们可以进行一些额外的处理,这些额外的处理只需要让bean实现对应的接口即可,那么spring就会在bean的生命周期调用我们实现的接口来处理该bean...一般情况下,在织入切面时,AOP 容器会为目标对象创建动态的创建一个代理对象。SpringAOP 就是以这种方式织入切面的。 织入:把切面应用到目标对象并创建新的代理对象的过程。...抽象类 JDK 中继承于 EventObject,在 Spring 框架中所有的事件都需要继承 ApplicationEvent,并且通过构造器参数 source 得到事件源。...所以父类模板方法中有两类方法: 共同的方法:所有子类都会用到的代码 不同的方法:子类要覆盖的方法,分为两种: 抽象方法:父类中的是抽象方法,子类必须覆盖 钩子方法:父类中是一个空方法,子类继承了默认也是空的

    36240

    Spring-bean之间的关系

    在Spring容器中,两个Bean之间 除了注入关系外,还存在 继承、依赖、引用 三种关系: 继承关系:在Spring容器当中允许使用abstract标签来定义一个父bean,parent标签来定义一个子...---- 继承 如果多个bean存在相同的配置信息,Spring允许定义一个父Bean,子bean将自动继承父bean的配置信息。...可以看到这两个bean都继承自abstractPlane这个父bean,在上面的代码中子bean就只改变了color属性,其他属性都跟父类相同。...---- 依赖 在Spring容器中,当使用depends-on标签建立对其他Bean的依赖关系时,Spring容器负责管理这些Bean的关系,当实例化一个Bean时,容器保证该Bean所依赖的Bean...---- 引用 在Spring容器中,当使用标签引用另外一个Bean时,但实际上两者并没有建立引用关系,即使我们编写错误,也需要在运行期才可以发现。

    37220

    灵活运用这9种Spring中的设计模式,老板肯定给你升职加薪!

    Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。...,对于实现了这些Aware接口的bean,在实例化bean时Spring会帮我们注入对应的BeanFactory的实例。...InitializingBean接口,实现了InitializingBean接口的bean,在实例化bean时Spring会帮我们调用接口中的方法。...实现原理: 切面在应用运行的时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。SpringAOP就是以这种方式织入切面的。...所以父类模板方法中有两类方法: 共同的方法:所有子类都会用到的代码 不同的方法:子类要覆盖的方法,分为两种: 抽象方法:父类中的是抽象方法,子类必须覆盖 钩子方法:父类中是一个空方法,子类继承了默认也是空的

    48500
    领券