Spring 实例化bean有几种方式?

Spring 实例化 Bean 是 IoC 容器的核心能力之一,主要有 6 种常见方式,我会从新手易懂的角度,由基础到进阶逐一讲解,并配合代码示例,让你清晰理解每种方式的使用场景和实现逻辑。

一、核心实例化方式(附代码示例)

1. 构造器实例化(最常用)

这是 Spring 默认的实例化方式,IoC 容器通过调用 Bean 的无参构造器创建实例(如果有参构造器,需通过配置指定参数)。

  • 适用场景:绝大多数普通业务 Bean(如 Service、Controller)。

  • 代码示例:

    复制代码
    // 1. 定义普通类(无参构造器默认存在,无需显式写)
    public class UserService {
        public UserService() {
            System.out.println("UserService 无参构造器执行");
        }
        
        public void sayHello() {
            System.out.println("Hello, Spring!");
        }
    }
    
    // 2. Spring 配置(XML 方式)
    <!-- applicationContext.xml -->
    <bean id="userService" class="com.example.UserService"/>
    
    // 3. 测试代码
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.sayHello(); // 输出:UserService 无参构造器执行 + Hello, Spring!
        }
    }

    如果是有参构造器,XML 配置需指定参数:

    xml

    复制代码
    <!-- 有参构造器实例化 -->
    <bean id="userService" class="com.example.UserService">
        <constructor-arg value="张三"/> <!-- 对应构造器的参数 -->
    </bean>
2. 静态工厂方法实例化

通过调用静态方法返回 Bean 实例,适用于需要统一控制实例创建逻辑的场景(如工具类、单例对象)。

  • 适用场景:第三方类库、自定义单例工厂。

  • 代码示例:

    复制代码
    // 1. 定义工厂类(包含静态方法)
    public class UserServiceFactory {
        // 静态工厂方法,返回 UserService 实例
        public static UserService createUserService() {
            return new UserService();
        }
    }
    
    // 2. Spring 配置
    <bean id="userService" class="com.example.UserServiceFactory" 
          factory-method="createUserService"/> <!-- 指定静态工厂方法 -->
    
    // 3. 测试(和构造器方式一致,Spring 会调用 createUserService() 创建实例)
3. 实例工厂方法实例化

通过调用非静态方法(即先创建工厂 Bean 实例,再调用其方法)返回 Bean 实例,适用于工厂类需要维护状态的场景。

  • 适用场景:工厂类需要依赖其他 Bean、或需要多实例工厂。

  • 代码示例:

    复制代码
    // 1. 定义实例工厂类(非静态方法)
    public class UserServiceInstanceFactory {
        public UserService createUserService() {
            return new UserService();
        }
    }
    
    // 2. Spring 配置(先定义工厂 Bean,再通过工厂 Bean 调用方法)
    <bean id="userServiceFactory" class="com.example.UserServiceInstanceFactory"/>
    <bean id="userService" factory-bean="userServiceFactory" 
          factory-method="createUserService"/>
4. FactoryBean 接口实例化(进阶)

这是 Spring 提供的专用工厂接口(注意和上面的 "工厂方法" 区分),实现该接口可以自定义 Bean 的创建逻辑,还能控制 Bean 的初始化、销毁。

  • 核心方法:

    • getObject():返回 Bean 实例;
    • getObjectType():返回 Bean 的类型;
    • isSingleton():是否单例(默认 true)。
  • 适用场景:复杂对象创建(如数据源、MyBatis 的 SqlSessionFactory)。

  • 代码示例:

    复制代码
    // 1. 实现 FactoryBean 接口
    public class UserServiceFactoryBean implements FactoryBean<UserService> {
        @Override
        public UserService getObject() throws Exception {
            return new UserService(); // 自定义创建逻辑
        }
    
        @Override
        public Class<?> getObjectType() {
            return UserService.class;
        }
    
        // 可选:指定是否单例(默认 true)
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    
    // 2. Spring 配置
    <bean id="userService" class="com.example.UserServiceFactoryBean"/>
    
    // 3. 测试(Spring 会自动调用 getObject() 获取实例)
5. 注解驱动实例化(主流)

基于注解的方式是现代 Spring 开发的主流,替代 XML 配置,核心注解包括:

  • @Component:通用注解(标注普通 Bean);

  • @Service:标注业务层 Bean;

  • @Controller:标注控制层 Bean;

  • @Repository:标注数据访问层 Bean;

  • @Configuration + @Bean:标注配置类,通过方法返回 Bean 实例。

  • 代码示例(@Component 方式):

    复制代码
    // 1. 标注注解
    @Service // 等同于在 XML 中定义 Bean
    public class UserService {
        public void sayHello() {
            System.out.println("Hello, Annotation!");
        }
    }
    
    // 2. 开启注解扫描(XML 或配置类)
    <!-- XML 方式开启扫描 -->
    <context:component-scan base-package="com.example"/>
    
    // 或配置类方式(推荐)
    @Configuration
    @ComponentScan("com.example") // 扫描指定包下的注解 Bean
    public class SpringConfig {}
    
    // 3. 测试
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService = context.getBean(UserService.class);
            userService.sayHello(); // 输出:Hello, Annotation!
        }
    }
  • 代码示例(@Configuration + @Bean 方式):

    复制代码
    // 1. 配置类中定义 Bean
    @Configuration
    public class SpringConfig {
        // 方法返回值即为 Bean 实例,方法名默认是 Bean 的 id
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
    
    // 2. 测试(直接获取 Bean)
6. 通过 BeanDefinition 手动实例化(底层)

这是最底层的方式,直接操作 Spring 的 BeanDefinition(Bean 的定义元数据),通过编程式方式向容器注册 Bean,适用于框架开发或动态创建 Bean。

  • 适用场景:自定义 Spring 扩展、动态生成 Bean。

  • 代码示例:

    复制代码
    public class Test {
        public static void main(String[] args) {
            // 1. 创建 BeanFactory 容器
            DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
            
            // 2. 构建 BeanDefinition(定义 Bean 的元数据)
            BeanDefinition beanDefinition = BeanDefinitionBuilder
                    .genericBeanDefinition(UserService.class)
                    .getBeanDefinition();
            
            // 3. 注册 BeanDefinition 到容器
            beanFactory.registerBeanDefinition("userService", beanDefinition);
            
            // 4. 获取 Bean 实例
            UserService userService = beanFactory.getBean("userService", UserService.class);
            userService.sayHello();
        }
    }

二、不同方式的使用场景总结

表格

实例化方式 核心特点 适用场景
构造器实例化 简单、默认支持 普通业务 Bean(无复杂创建逻辑)
静态工厂方法 统一控制实例创建 第三方类库、单例对象
实例工厂方法 工厂可维护状态、依赖其他 Bean 需多实例工厂、工厂依赖注入
FactoryBean 接口 自定义创建逻辑、控制初始化 复杂对象(数据源、SqlSessionFactory)
注解驱动实例化 简洁、主流 现代 Spring 项目(Spring Boot)
BeanDefinition 手动 底层、灵活 框架开发、动态创建 Bean

总结

  1. 日常开发优先用注解@Service/@Controller/@Bean 是 Spring Boot 主流,简洁高效;
  2. 基础方式是构造器:Spring 默认通过无参构造器实例化 Bean,是所有方式的基础;
  3. 复杂场景用工厂FactoryBean 适合复杂对象创建,静态 / 实例工厂适合统一控制实例逻辑。

核心记住:Spring 实例化 Bean 的本质是 IoC 容器根据 Bean 的定义(XML / 注解 / BeanDefinition),调用对应的创建逻辑(构造器 / 工厂方法)生成实例,最终将实例存入容器供使用。

相关推荐
冲上云霄的Jayden22 分钟前
Spring Ai WebClient、RestClient设置代理
spring·webclient·代理·restclient·gemini·region·springai
BduL OWED27 分钟前
Redis之Redis事务
java·数据库·redis
FastBean36 分钟前
BizAssert:一个轻量级、生产就绪的 Java 业务断言工具类
java·后端
疯狂的程序猴40 分钟前
iOS 多技术栈混淆实现,跨平台 App 混淆拆解与组合
后端·ios
zhuiyisuifeng43 分钟前
Node.js使用教程
java
李庆政3701 小时前
Reactor-core 响应式编程 spring-boot-starter-webflux
java·spring boot·reactor·响应式编程·reactor-core
是Smoky呢1 小时前
springAI+向量数据库+RAG入门案例
java·开发语言·ai编程
huabiangaozhi1 小时前
修改表字段属性,SQL总结
java·数据库·sql
请为小H留灯1 小时前
一键解决 IDEA 中 Java 项目变橙色的问题!!!
java·ide·maven·intellij-idea·java项目
法欧特斯卡雷特1 小时前
从 Kotlin 编译器 API 的变化开始: 2.3.20
android·后端·开源