BeanFactory和FactoryBean的区别

#新星杯·14天创作挑战营·第11期#

目录

1、Spring-core

2、控制反转(IoC)

2.1、定义

2.2、实现方式

1、BeanFactory

2、ApplicationContext

3、FactoryBean


  BeanFactory是容器,管理所有Bean(包括FactoryBean),FactoryBean是被管理的Bean,只是它有特殊能力可以创建其他Bean。

        Spring-core里面的ioc容器是通过BeanFactory和applicationContext来实现的,具体可参考:

Spring的核心模块原理介绍_spring 原理-CSDN博客


1、Spring-core

        Spring Core容器是Spring框架的核心模块,负责管理应用程序的配置和依赖关系,并通过**控制反转(IoC)和依赖注入(DI)**实现对象的创建、配置和生命周期管理。

如下图所示:

关于spring-core组件和spring-beans及spring-context的联系如下图所示:


2、控制反转(IoC)

2.1、定义

        IoC是Spring的核心思想,即对象的创建和依赖关系的管理由Spring容器(而非硬编码)完成。容器接管了对象生命周期的控制权。


2.2、实现方式

        通过BeanFactory或ApplicationContext容器来管理Bean,通俗来讲就是工厂和反射来进行实现。

1、BeanFactory

  • 定义BeanFactory接口体系

关于BeanFactory位于org.springframework.beans.factory包下;


package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;


    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    boolean containsBean(String name);

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    *******
}

代码示例如下:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class BeanFactoryExample {
    public static void main(String[] args) {
        // 1. 创建资源对象,指定配置文件位置
        ClassPathResource resource = new ClassPathResource("beans.xml");
        
        // 2. 创建BeanFactory容器
        BeanFactory factory = new XmlBeanFactory(resource);
        
        // 3. 从容器中获取bean (懒加载,此时才会真正创建UserService实例)
        UserService userService = (UserService) factory.getBean("userService");
        
        // 4. 使用bean
        userService.sayHello();
    }
}

// 简单的服务类
class UserService {
    public void sayHello() {
        System.out.println("Hello from UserService!");
    }
}

对应的 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="userService" class="com.example.UserService"/>
</beans>

2、ApplicationContext

使用xml文件读取bean的属性。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ApplicationContextExample {
    public static void main(String[] args) {
        // 1. 创建ApplicationContext容器 (立即加载并初始化所有单例bean)
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        
        // 2. 从容器中获取bean
        UserService userService = context.getBean("userService", UserService.class);
        
        // 3. 使用bean
        userService.sayHello();
        
        // 4. 关闭容器(某些实现类需要)
        ((ClassPathXmlApplicationContext) context).close();
    }
}

// 或者使用注解配置方式

// 或者使用注解配置方式
public class AnnotationConfigExample {
    public static void main(String[] args) {
        // 1. 创建基于注解的ApplicationContext
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 2. 获取bean
        UserService userService = context.getBean(UserService.class);
        
        // 3. 使用bean
        userService.sayHello();
    }
}

// 配置类
@Configuration
class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

3、FactoryBean

 FactoryBean 是一个接口,定义在 org.springframework.beans.factory 包中:

SqlSessionFactoryBean是一个FactoryBean。

// 获取的是SqlSessionFactory对象(由FactoryBean创建)
SqlSessionFactory sessionFactory = context.getBean("sqlSessionFactory");

// 获取FactoryBean本身(很少需要这样用)
SqlSessionFactoryBean factoryBean = 
    (SqlSessionFactoryBean) context.getBean("&sqlSessionFactory");

代码示例:

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    // 返回由FactoryBean创建的对象实例
    T getObject() throws Exception;

    // 返回创建对象的类型
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}

通过实现这个FactoryBean可以产出任意bean对象,返回的是getObject()方法返回的对象类型。

如下所示:

public class FactoryBeanTest implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

 注意:       

        如果要实现FactoryBeanTest 本身,可以context.getBean("&FactoryBeanTest")在获取的时候,通过&字符来实现,同时,这个也是懒加载模式。

小结

FactoryBean 是 Spring 中一个强大的扩展点:

  • 用于封装复杂对象的创建过程

  • 在框架集成中广泛使用(如 MyBatis, Hibernate 等)

  • 可以动态决定返回的对象类型

  • 通过 & 前缀可以获取 FactoryBean 本身

        理解 FactoryBean 的工作机制有助于更深入地掌握 Spring 容器的扩展方式,也能更好地使用各种与 Spring 集成的第三方框架。


总结

理解这两个概念的关键:

  • BeanFactory 是容器本身,是管理所有Bean的"大管家"

  • FactoryBean 是被管理的特殊Bean,是能够生产其他Bean的"小工厂"

  • 所有FactoryBean都由BeanFactory管理,而BeanFactory可以管理各种类型的Bean

        这种设计体现了Spring框架的扩展性和灵活性,通过FactoryBean机制可以方便地集成各种复杂的第三方库和框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值