简单了解Spring中BeanFactory与FactoryBean的区别

这篇文章主要介绍了简单了解Spring中beanfactoryfactorybean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

这篇文章主要介绍了简单了解Spring中beanfactoryfactorybean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在Spring中有beanfactoryfactorybean这2个接口,从名字来看很相似,比较容易搞混。

一、beanfactory

beanfactory一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean()、containsBean()等管理Bean的通用方法。Spring的容器都是它的具体实现如:

DefaultListablebeanfactory

Xmlbeanfactory

ApplicationContext

这些实现类又从不同的维度分别有不同的扩展。

1.1 BenaFactory源码

public interface beanfactory { /** * 用来获得实例的引用,并且区分factorybean区分。 * 如果使用bean的名字myJndiobject获取factorybean,返回的是一个工厂,而不是工厂的实例;如果需要获得工厂实例,需要转义。 */ String FACTORY_BEAN_PREFIX = "&"; /** * 根据bean的名称获取指定的bean实例,该实例可以是共享的,也可以是独立的. */ Object getBean(String name) throws BeansException; /** * 根据bean的名称获取指定的bean实例,该实例可以是共享的,也可以是独立的.并且增加一个类型的检验。 */ T getBean(String name, Class requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; /** * 根据给定类型返回匹配的bean实例. */ T getBean(Class requiredType) throws BeansException; T getBean(Class requiredType, Object... args) throws BeansException; /** * 检查spring的bean容器中是否包含有该bean */ boolean containsBean(String name); /** * 判断bean的作用域是否是singleton */ boolean isSingleton(String name) throws NoSuchBeanDeFinitionException; /** * 判断bena的作用域是否是prototype */ boolean isPrototype(String name) throws NoSuchBeanDeFinitionException; /** * 检查给定名称的bean是否和指定类型匹配.更确却的说是通过检查给定的bean,返回指定类型的目标对象 */ boolean isTypeMatch(String name, ResolvableType typetoMatch) throws NoSuchBeanDeFinitionException; boolean isTypeMatch(String name, Class> typetoMatch) throws NoSuchBeanDeFinitionException; /** * 获取给定名称的bean的class类型 */ Class> getType(String name) throws NoSuchBeanDeFinitionException; /** * 获取给定bean名称的别名,如果根据别名检索,将会获得原始bean名称。 * String[] getAliases(String name); }

1.2 使用场景

从Ioc容器中获取Bean(byName or byType):context.getBean("father", Father.class)、context.getBean("father")

检索Ioc容器中是否包含指定的Bean: context.containsBean("father")

判断Bean是否为单例: context.isSingleton("father")

二、factorybean

首先它是一个Bean,但又不仅仅是一个Bean。它是一个能生产或修饰对象生成的工厂Bean,类似于设计模式中的工厂模式和装饰器模式。它能在需要的时候生产一个对象,且不仅仅限于它自身,它能返回任何Bean的实例。2.1 factorybean源码public interface factorybean { /** * 从工厂中获取bean实例 */ T getobject() throws Exception; /** * 从工厂中获取bean实例对象的类型 */ Class> getobjectType(); /** * 工厂创建的对象是否是单例 */ boolean isSingleton(); }从它定义的接口可以看出,factorybean表现的是一个工厂的职责。 即一个Bean A如果实现了factorybean接口,那么A就变成了一个工厂,根据A的名称获取到的实际上是工厂调用getobject()返回的对象,而不是A本身,如果要获取工厂A自身的实例,那么需要在名称前面加上'&'符号。getobject('name')返回工厂中的实例getobject('&name')返回工厂本身的实例通常情况下,bean 无须自己实现工厂模式,Spring 容器担任了工厂的 角色;但少数情况下,容器中的 bean 本身就是工厂,作用是产生其他 bean 实例。由工厂 bean 产生的其他 bean 实例,不再由 Spring 容器产生,因此与普通 bean 的配置不同,不再需要提供 class 元素。2.2 示例先定义一个Bean实现factorybean接口:@Component public class MyBean implements factorybean { private String message; public MyBean() { this.message = "通过构造方法初始化实例"; } public MyBean(String message) { this.message = message; } @Override public Object getobject() throws Exception { // 这里并不一定要返回MyBean自身的实例,可以是其他任何对象的实例 return new MyBean("通过factorybean.getobject()创建实例"); } @Override public Class> getobjectType() { return MyBean.class; } public String getMessage() { return message; } @Override public boolean isSingleton() { return false; } }MyBean实现了factorybean接口的三个方法,getobject()是可以返回任何对象的实例的,这里测试就返回MyBean自身实例,且返回前给message字段赋值。同时在构造方法中也为message赋值。然后测试代码中先通过名称获取Bean实例,打印message的内容,再通过&+名称获取实例并打印message内容。@RunWith(springrunner.class) @SpringBoottest(classes = HelloApplication.class) public class factorybeanTest { @Autowired private ApplicationContext context; @Test public void test() { MyBean myBean1 = (MyBean) context.getBean("myBean");//返回工厂中的实例,调用factorybean.getobject()创建实例 System.out.println("myBean1 = " + myBean1.getMessage()); MyBean myBean2 = (MyBean) context.getBean("&myBean");//返回工厂本身,通过构造方法初始化实例 System.out.println("myBean2 = " + myBean2.getMessage()); System.out.println("myBean1.equals(myBean2) = " + myBean1.equals(myBean2)); } }打印结果:myBean1 = 通过factorybean.getobject()创建实例 myBean2 = 通过构造方法初始化实例 myBean1.equals(myBean2) = false2.3 使用场景说了这么多,为什么要有factorybean这个东西呢,有什么具体的作用吗?factorybean在Spring中最为典型的一个应用就是用来创建AOP的代理对象。我们知道AOP实际上是Spring在运行时创建了一个代理对象,也就是说这个对象,是我们在运行时创建的,而不是一开始就定义好的,这很符合工厂方法模式。更形象地说,AOP代理对象通过Java的反射机制,在运行时创建了一个代理对象,在代理对象的目标方法中根据业务要求织入了相应的方法。这个对象在Spring中就是――Proxyfactorybean。所以,factorybean为我们实例化Bean提供了一个更为灵活的方式,我们可以通过factorybean创建出更为复杂的Bean实例。三、区别他们两个都是个工厂,但factorybean本质上还是一个Bean,也归beanfactory管理beanfactoryspring容器的顶层接口,factorybean更类似于用户自定义的工厂接口。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...