Spring - BeanFactory和FactoryBean的区别
总结
BeanFactory和FactoryBean其实没有什么比较性的,只是两者的名称特别接近,所以有时候会拿出来比较一番。
- BeanFactory是提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范。
- FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。
BeanFactory
- BeanFactory是一个接口,提供了IOC容器最基本的形式(包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖),给具体的IOC容器的实现(如:ApplicationContext接口,XmlBeanFactory)提供了规范。
- BeanFactory接口是无法支持spring的许多插件,如AOP功能、Web应用等。
- ApplicationContext接口,它由BeanFactory接口派生而来。ApplicationContext包含BeanFactory的所有功能。
package org.springframework.beans.factory; import org.springframework.beans.BeansException; public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; //返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常 <T> T getBean(String name, Class<T> requiredType) throws BeansException; //返回以给定名称注册的bean实例,并转换为给定class类型 <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); //判断工厂中是否包含给定名称的bean定义,若有则返回true boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //判断给定名称的bean定义是否为单例模式 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; //返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常 String[] getAliases(String name); //返回给定bean名称的所有别名 }
FactoryBean
- FactoryBean是一个(工厂类)接口,通过实现该接口,定制实例化Bean的逻辑。(在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。)
- FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。
- 当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。
FactoryBean源码
package org.springframework.beans.factory; public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton(); }
FactoryBean的实现类
import org.springframework.beans.factory.FactoryBean; /** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:19:31 * @parameter * @return */ public class FactoryBeanPojo implements FactoryBean{ private String type; @Override public Object getObject() throws Exception { if("student".equals(type)){ return new Student(); }else{ return new School(); } } @Override public Class getObjectType() { return School.class; } @Override public boolean isSingleton() { return true; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
普通的bean
/** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:13:18 * @parameter * @return */ public class School { private String schoolName; private String address; private int studentNumber; public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getStudentNumber() { return studentNumber; } public void setStudentNumber(int studentNumber) { this.studentNumber = studentNumber; } @Override public String toString() { return "School [schoolName=" + schoolName + ", address=" + address + ", studentNumber=" + studentNumber + "]"; } }
XML配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <bean id="student" class="com.spring.bean.Student"> <property name="name" value="zhangsan" /> </bean> <bean id="school" class="com.spring.bean.School"> </bean> <bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo"> <property name="type" value="student" /> </bean> </beans>
测试类
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.bean.FactoryBeanPojo; /** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:11:35 * @parameter * @return */ public class FactoryBeanTest { public static void main(String[] args){ String url = "com/spring/config/BeanConfig.xml"; ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url); Object school= cpxa.getBean("factoryBeanPojo"); FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo"); System.out.println(school.getClass().getName()); System.out.println(factoryBeanPojo.getClass().getName()); } }
输出的结果:
loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml] com.spring.bean.Student com.spring.bean.FactoryBeanPojo
从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。
参考文献
版权声明:本文为CSDN博主「wangbiao007」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/wangbiao007/article/details/53183764
https://www.cnblogs.com/aspirant/p/9082858.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?