Spring|Spring BeanFactory与FactoryBean的区别
1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
实例化容器
1 Resource resource = new FileSystemResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ClassPathResource resource = new ClassPathResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); 3 BeanFactory factory = (BeanFactory) context;
【Spring|Spring BeanFactory与FactoryBean的区别】 基本就是这些了,接着使用getBean(String beanName)方法就可以取得bean的实例;BeanFactory提供的方法及其简单,仅提供了六种方法供客户调用:
- boolean containsBean(String beanName) 判断工厂中是否包含给定名称的bean定义,若有则返回true
- Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
- Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
- Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
- boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
- String[] getAliases(String name) 返回给定bean名称的所有别名
BeanFactory实例化Bean的过程:
1、 调用bean的默认构造方法(或指定的构造方法),生成bean1。
2、 将配置文件中配置的属性值注入bean1,生成bean2。
3、 如bean实现了InitalizingBean接口,则执行afterPropertiesSet()方法,生成bean3。
4、 如配置文件配置了init-method属性,则执行指定的方法,生成bean4。
构造函数-->set-->InitalizingBean#afterPropertiesSet()-->init-method
2, FactoryBean
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean
通常来讲,根据XML的节点中配置的class路径,Spring可以通过反射机制来实例化。
如:
但实际工作中,实例化一个对象并不如此简单。比如要在实例化的时候做一些复杂的处理。这就用上FactoryBean了。
比如最常用的Quartz框架,我们在配置调度任务的时候,配置的都是FactoryBean。
FactoryBean隐藏了许多实例化的复杂细节,方便上层调用。
如果在中配置的是FactoryBean,那么getBean()返回的其实是FactoryBean#getObject()返回的对象。
如:
getBean("beanA")返回的其实是BeanAFactoryBean#getObject()返回的对象,至于是什么,就由BeanAFactoryBean来决定了。
要想返回BeanFactory的实例,应该getBean("&beanA")。
我们先来看下FactoryBean的接口定义: [java]view plain copy
- "white-space:pre">public interface FactoryBean
{ - //返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中。
- T getObject() throws Exception;
- //返回FactoryBean创建的bean类型。
- Class> getObjectType();
- //返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。
- boolean isSingleton();
- }
- public class Person {
- private String name;
- private String address;
- private int age;
- }
- public class PersonFactoryBean implements FactoryBean{
- private String personInfo;
- public Person getObject() throws Exception {
- Person person =newPerson () ;
- String []infos =personInfo.split ( "," ) ;
- person.setName(infos[0]);
- person.setAddress(infos[1]);
- person.setAge(Integer.parseInt(infos[2]));
- return person;
- }
- public Class getObjectType() {
- return Person.class;
- }
- public boolean isSingleton() {
- return true;
- }
- }
很多开源项目在集成Spring 时都使用到FactoryBean,比如 MyBatis3 提供 mybatis-spring项目中的
org.mybatis.spring.SqlSessionFactoryBean
:
org.mybatis.spring.SqlSessionFactoryBean
如下:
package org.mybatis.spring;
public class SqlSessionFactoryBean implements FactoryBean, InitializingBean, ApplicationListener {
private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);
......
}
另外,阿里开源的分布式服务框架 Dubbo 中的Consumer 也使用到了FactoryBean:
对应的Bean是com.alibaba.dubbo.config.spring.ReferenceBean
类,如下:
public class ReferenceBean extends ReferenceConfig implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {}
作者:FX_SKY
链接:https://www.jianshu.com/p/6f0a59623090
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- FactoryBean:是一个Java Bean,但是它是一个能生产对象的工厂Bean,它的实现和工厂模式及修饰器模式很像。比如下:我们把bean比作是人,那么FactoryBean可以算是一个女人,首先它本身也是一个人,但它能够生产人。【挺尴尬的比喻】。
- BeanFactory:这就是一个Factory,是一个IOC容器或者叫对象工厂,它里面存着很多的bean。还用上面那个比如:如果bean是人,那么它可以理解成学校,学校里面很多人,学校管理这么多的人。
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- Activiti(一)SpringBoot2集成Activiti6
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题