BeanFactory和FactoryBean的区别
目录
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. 使用beanuserService.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/beanshttp://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. 从容器中获取beanUserService userService = context.getBean("userService", UserService.class);// 3. 使用beanuserService.sayHello();// 4. 关闭容器(某些实现类需要)((ClassPathXmlApplicationContext) context).close();}
}
// 或者使用注解配置方式
// 或者使用注解配置方式
public class AnnotationConfigExample {public static void main(String[] args) {// 1. 创建基于注解的ApplicationContextApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 2. 获取beanUserService userService = context.getBean(UserService.class);// 3. 使用beanuserService.sayHello();}
}// 配置类
@Configuration
class AppConfig {@Beanpublic 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 {@Overridepublic Object getObject() throws Exception {return new User();}@Overridepublic 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
机制可以方便地集成各种复杂的第三方库和框架。