Spring实例化bean有几种方式

Spring 实例化 Bean 主要有三种核心方式:构造器实例化、静态工厂方法实例化和实例工厂方法实例化,其中构造器实例化是最常用的方式。

1. 构造器实例化(默认方式)

Spring 容器通过调用 Bean 类的构造器(默认无参构造器或有参构造器)来创建实例,这是最基础、最常用的方式。

无参构造器实例化:Bean 类必须提供无参构造器(若未显式定义任何构造器,Java 会默认生成)。

<!-- 配置文件方式 -->
<bean id="userService" class="com.example.UserService"/>
// 注解方式(@Component、@Service等)
@Service
public class UserService {
    // 无参构造器(默认存在)
}

有参构造器实例化:需在配置中指定构造器参数,Spring 会根据参数类型、索引或名称匹配对应的构造器。

<bean id="user" class="com.example.User">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="Alice"/>
</bean>

2. 静态工厂方法实例化

通过调用一个静态工厂类的静态方法来创建 Bean 实例,适用于实例创建逻辑复杂,需封装在工厂中的场景。

1.定义静态工厂类和静态方法。
    
public class UserStaticFactory {
    // 静态工厂方法
    public static User createUser() {
        return new User(2, "Bob");
    }
}

2.在配置中指定工厂类和静态方法。

<bean id="userByStaticFactory" 
      class="com.example.UserStaticFactory" 
      factory-method="createUser"/>

3. 实例工厂方法实例化

通过调用一个非静态工厂类的实例方法来创建 Bean 实例,工厂类本身也需要作为一个 Bean 被 Spring 管理。

1.定义实例工厂类和实例方法。

public class UserInstanceFactory {
    // 实例工厂方法(非静态)
    public User createUser() {
        return new User(3, "Charlie");
    }
}

2.先配置工厂 Bean,再配置目标 Bean,指定工厂 Bean 和实例方法。

<!-- 配置实例工厂Bean -->
<bean id="userInstanceFactory" class="com.example.UserInstanceFactory"/>
<!-- 通过工厂Bean的实例方法创建目标Bean -->
<bean id="userByInstanceFactory" 
      factory-bean="userInstanceFactory" 
      factory-method="createUser"/>

4.factoryBean

FactoryBean 是 Spring 提供的一种特殊 Bean,它本身不直接作为业务对象,而是专门用于创建和管理其他 Bean 实例的“工厂”。与普通实例工厂方法不同,FactoryBean 是 Spring 容器级别的扩展点,使用更灵活。

核心原理

当 Spring 容器发现一个 Bean 的类型是 FactoryBean 时,它不会直接返回该 Bean 本身,而是会调用其 getObject() 方法,并将该方法的返回值作为最终的 Bean 实例返回给使用者。

实现步骤

实现 FactoryBean 接口来实例化 Bean,通常分为以下3步:

1.实现 FactoryBean 接口

自定义一个类实现 org.springframework.beans.factory.FactoryBean 接口,并实现其3个核心方法。

import org.springframework.beans.factory.FactoryBean;

// T 为要创建的目标 Bean 类型
public class UserFactoryBean implements FactoryBean<User> {

    /**
     * 核心方法:返回目标 Bean 的实例
     * 复杂的创建逻辑(如依赖注入、初始化配置)可在此实现
     */
    @Override
    public User getObject() throws Exception {
        User user = new User();
        user.setId(4);
        user.setName("David");
        // 模拟复杂逻辑:如调用其他服务、读取配置等
        return user;
    }

    /**
     * 返回目标 Bean 的类型
     */
    @Override
    public Class<?> getObjectType() {
        return User.class;
    }

    /**
     * 指定目标 Bean 是否为单例(默认 true)
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}
2.配置 FactoryBean 到 Spring 容器

将自定义的 FactoryBean 本身作为一个普通 Bean 配置到 Spring 中(XML 或注解方式均可)。

<!-- XML 配置方式 -->
<bean id="userFactoryBean" class="com.example.UserFactoryBean"/>
// 注解配置方式(@Component)
@Component("userFactoryBean")
public class UserFactoryBean implements FactoryBean<User> {
    // 实现同上
}
3.获取目标 Bean

从 Spring 容器中获取的并非 UserFactoryBean 实例,而是其 getObject() 方法返回的 User 实例。

@Test
public void test6() {
    // 测试类
    //通过注解的方式生成bean的测试
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    User user = (User) context.getBean("myFactoryBean");
    System.out.println(user);
    //获取工厂本身
    UserFactoryBean userFactoryBean = (UserFactoryBean) context.getBean("&myFactoryBean");
    System.out.println(userFactoryBean);

}

关键特点

  • 隐藏创建细节:将目标 Bean 复杂的创建逻辑(如依赖组装、多步骤初始化)封装在 FactoryBean 中,使用者无需关心。

  • 容器集成度高:FactoryBean 本身受 Spring 容器管理,可以注入其他 Bean、感知容器生命周期(如实现 InitializingBean)。

  • 单例/多例控制:通过 isSingleton() 方法可灵活控制目标 Bean 是单例(默认)还是多例。

典型应用场景

  • 整合第三方框架:如 MyBatis 中的 SqlSessionFactoryBean,Spring 整合 Redis 时的 RedisTemplate 工厂等。

  • 创建复杂实例:当一个 Bean 的创建需要大量配置(如读取配置文件、调用多个服务)时,使用 FactoryBean 封装逻辑。

总结

实例化方式核心特点适用场景
构造器实例化简单直接,Spring 默认方式大多数普通 Bean,无复杂创建逻辑
静态工厂实例化通过静态方法创建,工厂无需实例化复杂创建逻辑,需封装且工厂无需状态
实例工厂实例化通过实例方法创建,工厂需被 Spring 管理复杂创建逻辑,工厂本身需要维护状态
factoryBean实例化实现 FactoryBean 接口能感知 Spring 容器,可注入其他 Bean,配置简单,只需注册 FactoryBean 本身,可集成 Spring 生命周期接口(如 DisposableBean)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值