当前位置: 代码网 > it编程>编程语言>Java > Spring通过factory-method实例化Bean详解与常见错误排查

Spring通过factory-method实例化Bean详解与常见错误排查

2026年09月22日 Java 我要评论
一、配置解读你给出的配置片段是:<bean id="starbean" class="com.xie.spring.starfactory" factory-method="get">&l

一、配置解读

你给出的配置片段是:

<bean id="starbean" class="com.xie.spring.starfactory" factory-method="get">
</bean>

这段配置的含义是:spring 会调用 com.xie.spring.starfactory 类中的静态方法 get(),用它的返回值作为容器中 starbean 这个 bean 的实例。

也就是说,容器里 starbean 的类型取决于 get() 方法的返回类型,而不是 starfactory 这个类本身。

二、静态工厂方法实例化的前提条件

要让这段配置正常工作,必须满足以下条件:

1. get() 必须是静态方法

public class starfactory {
    public static star get() {
        star star = new star();
        star.setname("太阳");
        return star;
    }
}

如果 get() 不是 static 的,spring 启动时会报错,因为它无法在没有工厂实例的情况下调用实例方法。

2. get() 的返回类型必须与 getbean() 时的期望类型一致

star star = context.getbean("starbean", star.class);

如果 get() 返回的是 star,注入成功。如果返回的是 starfactory 或其他类型,就会抛出 beannotofrequiredtypeexception

3. 如果 get() 有参数,必须用 <constructor-arg> 传递

<bean id="starbean" class="com.xie.spring.starfactory" factory-method="get">
    <constructor-arg name="name" value="太阳"/>
</bean>

注意:这里虽然标签名是 constructor-arg,但实际是传给工厂方法的参数,不是构造方法参数。不能用 <property>

三、与实例工厂方法的对比

如果 get() 不是静态方法,就必须改用实例工厂写法:

<!-- 先定义工厂 bean -->
<bean id="starfactory" class="com.xie.spring.starfactory"/>
<!-- 再通过工厂实例调用方法 -->
<bean id="starbean" factory-bean="starfactory" factory-method="get"/>

此时第二个 <bean> 不能再写 class 属性。否则容器里存放的将是 starfactory 实例,而不是 get() 返回的产品,调用 getbean("starbean", star.class) 时就会报类型不匹配。

对比维度静态工厂方法实例工厂方法
工厂方法类型static非静态
xml 配置class + factory-methodfactory-bean + factory-method
工厂是否需要实例化不需要需要,且由 spring 管理
工厂能否注入依赖不能可以

四、常见错误:beannotofrequiredtypeexception

你之前遇到的报错是:

bean named 'starbean' is expected to be of type 'com.xie.spring.star' 
but was actually of type 'com.xie.spring.starfactory'

这个异常表示:你试图从容器中获取名为 starbean 的 bean,期望类型是 star,但容器中实际存放的却是 starfactory 类型的实例。

根本原因

出现这个错误,通常是因为配置或代码中,starbean 被定义成了 starfactory 本身,而不是通过工厂方法创建出的 star 对象。常见情况有:

忘记写 factory-method

<bean id="starbean" class="com.xie.spring.starfactory"/>

spring 直接实例化 starfactory,自然类型不匹配。

factory-method 方法返回了工厂自身

public static starfactory get() {
    return new starfactory();  // 返回的是工厂,不是产品
}

实例工厂方法配置错误

<bean id="starbean" class="com.xie.spring.starfactory"/>

应该写成 factory-bean 引用,而不是直接写 class

使用 factorybean 接口时获取方式错误 如果 starfactory 实现了 factorybean<star>,那么:

  • getbean("starbean") 返回 star
  • getbean("&starbean") 返回 starfactory 写反了就会类型不匹配。

五、完整正确示例

java 类:

public class star {
    private string name;
    // getter/setter/tostring
}

public class starfactory {
    public static star get() {
        star star = new star();
        star.setname("太阳");
        return star;
    }
}

beans.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"
       xsi:schemalocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="starbean" class="com.xie.spring.starfactory" factory-method="get"/>
</beans>

测试代码:

public class testfirstbean {
    @test
    public void test() {
        applicationcontext context = new classpathxmlapplicationcontext("beans.xml");
        star star = context.getbean("starbean", star.class);
        system.out.println(star);  // star{name='太阳'}
    }
}

六、排查步骤

  1. 打开 spring 的 xml 配置文件。
  2. 找到 id="starbean" 的 bean 定义。
  3. 检查:
    • 是否使用了 factory-method
    • 如果是静态工厂,class 是否指向工厂类?
    • 如果是实例工厂,是否配置了 factory-beanfactory-method
    • 如果实现了 factorybean,是否通过 &starbean 获取工厂?
  4. 确认工厂方法的返回类型是 star,而不是 starfactory
  5. 先不指定类型获取 bean,打印实际类型:
object bean = context.getbean("starbean");
system.out.println(bean.getclass().getname());

如果输出 com.xie.spring.star,说明配置正确;如果输出 com.xie.spring.starfactory,说明工厂方法返回了工厂自身。

七、总结

维度核心要点
配置含义调用静态工厂方法 get(),用返回值作为 bean
前提条件get() 必须是 static,返回类型必须是目标类型
参数传递<constructor-arg>,不是 <property>
实例工厂factory-bean + factory-method,不能再写 class
常见错误beannotofrequiredtypeexception,容器中存放的是工厂而非产品
排查方法检查 factory-method、返回类型、获取方式
正确获取getbean("starbean", star.class) 获取产品;getbean("&starbean") 获取工厂(仅 factorybean 场景)

理解静态工厂、实例工厂和 factorybean 的区别,确保容器中存放的是工厂方法返回的产品,而不是工厂本身,就能避免这类错误。

以上就是spring通过factory-method实例化bean详解与常见错误排查的详细内容,更多关于spring factory-method实例化bean的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com