BeanFactory与FactoryBean的区别与联系

BeanFactory顾名思义:生产和管理bean的工厂。它是IOC容器的规范接口,Spring中有很多个BeanFactory的实现,如DefaultListableBeanFactory,XmlBeanFactory,ClassPathXmlApplicationContext,ApplicationContext等等。

public interface BeanFactory {

	/** 用于区分FactoryBean与FactoryBean返回的实例
	 *  如getBean("&PeopleBeanFactory"); 将返回peopleBeanFactory实例
	 *  而getBean("peopleBeanFactory");将返回getObject()的返回对象
	 */
	String FACTORY_BEAN_PREFIX = "&";
	// 获取bean的方法
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	<T> T getBean(Class<T> requiredType) throws BeansException;
	Object getBean(String name, Object... args) throws BeansException;
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	// 是否存在bean
	boolean containsBean(String name);
	// 是否为单例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	//是否存在另一个实例
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	//比较此bean的Class对象是否为目标Class对象
	boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
	// 获取bean的Class对象
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	// 获取别名
	String[] getAliases(String name);

}

而FactoryBean,看到后缀我们应该明白它是一个Bean,那它当然也由BeanFactory来进行实例化和管理的,但是它也是Bean的工厂,为什么呢?它有什么用呢?我们来看一下这个接口

public interface FactoryBean<T> {

	// 获取对象
	T getObject() throws Exception;
	// 获取对象的Class对象
	Class<?> getObjectType();
	// 是否单例
	boolean isSingleton();

}
BeanFactory beanfactory = new ClassPathXmlApplicationContext("applicationContext.xml");
beanfactory.getBean("PeopleFactoryBean");

当你通过上面getBean()获取的对象,其实是调用的getObject()方法返回的对象。就相当于对你要返回的对象加工了一下。

例子:

public class People {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
@Component
public class PeopleFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
       People people = new People();
       people.setName("某某");
        return people;
    }

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

    @Override
    public boolean isSingleton() {
        return false;
    }
}
public class App 
{
    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");
        People people = (People) beanFactory.getBean("peopleFactoryBean");
        System.out.println(people.getName());
    }
}

那么在预料内的话,Console打印的应该是 某某

嗯,果然是。

还记得之前BeanFactory的第一个字段吗?

String FACTORY_BEAN_PREFIX = "&";

我们如果把main函数改成这样

public class App 
{
    public static void main(String[] args) throws Exception {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");
        PeopleFactoryBean factoryBean = (PeopleFactoryBean) beanFactory.getBean("&peopleFactoryBean");
        People people = (People) factoryBean.getObject();
        System.out.println(people.getName());
    }
}

那么获取的就是PeopleFactoryBean实例,然后通过它的getObject()方法可以获取到对应的实例

打印输出还是 某某

总结:所以说BeanFactory是来对Bean进行实例化和管理的,FactoryBean是用来对实例进行创建和修饰的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

聊聊storm的WindowedBolt

storm-2.0.0/storm-client/src/jvm/org/apache/storm/topology/IWindowedBolt.java

25040
来自专栏java系列博客

HibernateCallback 的用法

11920
来自专栏函数式编程语言及工具

SDP(9):MongoDB-Scala - data access and modeling

    MongoDB是一种文件型数据库,对数据格式没有硬性要求,所以可以实现灵活多变的数据存储和读取。MongoDB又是一种分布式数据库,与传统关系数据库不同...

39640
来自专栏个人分享

Socket与Http方式解析发送xml消息封装中间件jar包

  最近项目代码中太多重复的编写Document,不同的接口需要不同的模板,于是重写提取公共部分打成jar包,方便各个系统统一使用~

17030
来自专栏cmazxiaoma的架构师之路

SpringMVC中出现的线程安全问题分析

(ps:前几个星期发生的事情)之前同事跟我说不要使用@Autowired方式注入HttpServletRequest(ps:我们的代码之前用的是第2种方式)。同...

77720
来自专栏小樱的经验随笔

BZOJ 2456: mode(新生必做的水题)

2456: mode Time Limit: 1 Sec  Memory Limit: 1 MB Submit: 4868  Solved: 2039 Des...

27660
来自专栏小樱的经验随笔

Code forces 719A Vitya in the Countryside

A. Vitya in the Countryside time limit per test:1 second memory limit per test:2...

36060
来自专栏后端沉思录

简话bean加载

以上代码就是LiosServiceServiceImpl类中引用了LiosTestA,LiosTestA类中引用了LiosTestB,今天的问题是LiosSer...

10120
来自专栏前端说吧

正则表达式验证汇总

一、收集1  (转自https://blog.csdn.net/jumtre/article/details/13775351)

13010
来自专栏desperate633

LeetCode Fizz Buzz题目分析代码

Write a program that outputs the string representation of numbers from 1 to n.

8910

扫码关注云+社区

领取腾讯云代金券