一文读懂BeanFactory和FactoryBean区别
2024-09-06 06:26:04
一直以来,很多人对于Spring中的BeanFactory和FactoryBean都是分不清楚的
BeanFactory
这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean
方法等
The root interface for accessing a Spring bean container. This is the basic client view of a bean container;
定义方法:
getBean(String name)
: Spring容器中获取对应Bean对象的方法,如存在,则返回该对象containsBean(String name)
:Spring容器中是否存在该对象isSingleton(String name)
:通过beanName是否为单例对象isPrototype(String name)
:判断bean对象是否为多例对象isTypeMatch(String name, ResolvableType typeToMatch)
:判断name
值获取出来的bean与typeToMath
是否匹配getType(String name)
:获取Bean的Class类型getAliases(String name)
:获取name所对应的所有的别名
主要的实现类(包括抽象类):
AbstractBeanFactory
:抽象Bean工厂,绝大部分的实现类,都是继承于他DefaultListableBeanFactory
:Spring默认的工厂类XmlBeanFactory
:前期使用XML配置用的比较多的时候用的Bean工厂AbstractXmlApplicationContext
:抽象应用容器上下文对象ClassPathXmlApplicationContext
:XML解析上下文对象,用户创建Bean对象我们早期写Spring的时候用的就是他
使用方式:
- 使用
ClassPathXmlApplicationContext
读取对应的xml文件实例对应上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
BeanFactory factory = (BeanFactory) context;
FactoryBean
该类是SpringIOC容器是创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式
* Interface to be implemented by objects used within a {@link BeanFactory} which
* are themselves factories for individual objects. If a bean implements this
* interface, it is used as a factory for an object to expose, not directly as a
* bean instance that will be exposed itself.有些人就要问了,我直接使用Spring默认方式创建Bean不香么,为啥还要用FactoryBean做啥,在某些情况下,对于实例Bean对象比较复杂的情况下,使用传统方式创建bean会比较复杂,例如(使用xml配置),这样就出现了FactoryBean接口,可以让用户通过实现该接口来自定义该Bean接口的实例化过程。即包装一层,将复杂的初始化过程包装,让调用者无需关系具体实现细节。
方法:
T getObject()
:返回实例Class<?> getObjectType();
:返回该装饰对象的Bean的类型default boolean isSingleton()
:Bean是否为单例
常用类
ProxyFactoryBean
:Aop代理BeanGsonFactoryBean
:Gson
使用
- Spring XML方式
application.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="demo" class="cn.lonecloud.spring.example.bo.Person">
<property name="age" value="10"/>
<property name="name" value="xiaoMing"/>
</bean>
<bean id="demoFromFactory" class="cn.lonecloud.spring.example.bean.PersonFactoryBean">
<property name="initStr" value="10,init from factory"/>
</bean>
</beans>
personFactoryBean.java
package cn.lonecloud.spring.example.bean;
import cn.lonecloud.spring.example.bo.Person;
import org.springframework.beans.factory.FactoryBean;
import java.util.Objects;
/**
* TODO
*
* @author lonecloud <lonecloud@aliyun.com>
* @date 2020/8/4 23:39
* @since v1.0
*/
public class PersonFactoryBean implements FactoryBean<Person> {
/**
* 初始化Str
*/
private String initStr;
@Override
public Person getObject() throws Exception {
//这里我需要获取对应参数
Objects.requireNonNull(initStr);
String[] split = initStr.split(",");
Person p=new Person();
p.setAge(Integer.parseInt(split[0]));
p.setName(split[1]);
//这里可能需要还要有其他复杂事情需要处理
return p;
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
public String getInitStr() {
return initStr;
}
public void setInitStr(String initStr) {
this.initStr = initStr;
}
}
main方法
package cn.lonecloud.spring.example.factory;
import cn.lonecloud.spring.example.bo.Person;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* BeanFactory 例子
*
* @author lonecloud <lonecloud@aliyun.com>
* @date 2020/8/4 23:32
* @since v1.0
*/
public class SpringBeanFactoryMain {
public static void main(String[] args) {
//这个是BeanFactory
BeanFactory beanFactory = new ClassPathXmlApplicationContext("application.xml");
//获取对应的对象化
Object demo = beanFactory.getBean("demo");
System.out.println(demo instanceof Person);
System.out.println(demo);
//获取从工厂Bean中获取对象
Person demoFromFactory = beanFactory.getBean("demoFromFactory", Person.class);
System.out.println(demoFromFactory);
//获取对应的personFactory
Object bean = beanFactory.getBean("&demoFromFactory");
System.out.println(bean instanceof PersonFactoryBean);
PersonFactoryBean factoryBean=(PersonFactoryBean) bean;
System.out.println("初始化参数为:"+factoryBean.getInitStr());
}
}
输出
true
Person{name='xiaoMing', age=10}
Person{name='init from factory', age=10}
true
初始化参数为:10,init from factory
区别
- BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范,
- FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节。
代码:GitHub地址
最新文章
- Delphi使用ADO进行数据库编程
- 如何使 WebAPI 自动生成漂亮又实用在线API文档
- 关于mouse_event和sendinput无效的原因
- python 3次登录
- JSBinding / FAQ &; Trouble Shooting
- 如何知道btree树的高度
- cocos2d CCDictionary
- 一些用于数据整理的excel函数
- bug_ _ 常见的bug1
- javascript注意点(1)
- Part 71 Code snippets in visual studio
- 有关C++ std::string 类的类型转换 其他语言永远无法理解的伤
- mysql - 初探
- 一、Autofac入门
- hadoop 学习
- Windows Azure Table Storage 解决 Guid 查询问题
- js与AMD模块加载
- SVN服务器搭建(一)
- JAVA线程sleep和wait方法区别
- lazyMan
热门文章
- 学习MySQL这一篇就够了
- matpltlib 示例
- The JOIN operation -- SQLZOO
- PHP array_walk_recursive() 函数
- 错误记录:MIME type may not contain reserved characters
- react-ts模板/脚手架
- linux条件测试操作(test)和if判断语句,while循环语句,break控制语句和for循环和case多分枝语句和select语句
- tensorflow2.0 实现gpu和cpu切换
- 数位DP 学习笔记
- 【转】一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结