Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

1. BeanFactory

  BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

  Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。

  实例化容器

 Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
 ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
BeanFactory factory = (BeanFactory) context;

基本就是这些了,接着使用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名称的所有别名

2. FactoryBean

  以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

  例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。

 /**
* my factory bean<p>
* 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出
* @author daniel.zhao
*
*/
public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean { private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class); private String interfaceName; private Object target; private Object proxyObj; @Override
public void destroy() throws Exception {
logger.debug("destroy......");
} @Override
public void afterPropertiesSet() throws Exception {
proxyObj = Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[] { Class.forName(interfaceName) },
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
logger.debug("invoke method......" + method.getName());
logger.debug("invoke method before......" + System.currentTimeMillis());
Object result = method.invoke(target, args);
logger.debug("invoke method after......" + System.currentTimeMillis());
return result;
} });
logger.debug("afterPropertiesSet......");
} @Override
public Object getObject() throws Exception {
logger.debug("getObject......");
return proxyObj;
} @Override
public Class<?> getObjectType() {
return proxyObj == null ? Object.class : proxyObj.getClass();
} @Override
public boolean isSingleton() {
return true;
} public String getInterfaceName() {
return interfaceName;
} public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
} public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} public Object getProxyObj() {
return proxyObj;
} public void setProxyObj(Object proxyObj) {
this.proxyObj = proxyObj;
} }

XML-Bean配置如下

 <bean id="fbHelloWorldService" class="com.ebao.xxx.MyFactoryBean">
<property name="interfaceName" value="com.ebao.xxx.HelloWorldService" />
<property name="target" ref="helloWorldService" />
</bean>

Junit Test class

 @RunWith(JUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyFactoryBeanConfig.class })
public class MyFactoryBeanTest { @Autowired
private ApplicationContext context; /**
* 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理
* 从ApplicationContext中获取自定义的FactoryBean
* context.getBean(String beanName) ---> 最终获取到的Object是FactoryBean.getObejct(),
* 使用Proxy.newInstance生成service的代理类
*/
@Test
public void testFactoryBean() {
HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService");
helloWorldService.getBeanName();
helloWorldService.sayHello();
}
}

其实FactoryBean这栋特点,可以实现很多有用的功能,实现大家多多评论多多补充,一起探讨。

Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法的更多相关文章

  1. Spring BeanFactory 与 FactoryBean 的区别

    BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...

  2. BeanFactory 和FactoryBean的区别

    转自:https://www.cnblogs.com/aspirant/p/9082858.html BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是 ...

  3. Spring中BeanFactory与FactoryBean的区别

    在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层 ...

  4. 【Java面试】Spring中 BeanFactory和FactoryBean的区别

    一个工作了六年多的粉丝,胸有成竹的去京东面试. 然后被Spring里面的一个问题卡住,唉,我和他说,6年啦,Spring都没搞明白? 那怎么去让面试官给你通过呢? 这个问题是: Spring中Bean ...

  5. BeanFactory和FactoryBean的区别

    转自:http://blog.csdn.net/wangbiao007/article/details/53183764 1.BeanFactory BeanFactory是IOC最基本的容器,负责生 ...

  6. 转:BeanFactory和FactoryBean的区别

    一.BeanFactory简介 BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是一种典型的BeanFactory.原始的BeanFactory无法支持 ...

  7. spring中BeanFactory和FactoryBean的区别

    共同点: 都是接口 区别: BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂 在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器 ...

  8. 【Spring】2、BeanFactory 和FactoryBean的区别

    转自:http://chenzehe.iteye.com/blog/1481476 1. BeanFactory BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的 ...

  9. spring中的BeanFactory和FactoryBean的区别与联系

    首先,这俩都是个接口… 实现 BeanFactory 接口的类表明此类是一个工厂,作用就是配置.新建.管理 各种Bean. 而 实现 FactoryBean 的类表明此类也是一个Bean,类型为工厂B ...

随机推荐

  1. 学习python二三事儿(二)

    多个变量赋值 Python允许你同时为多个变量赋值.例如: a = b = c = 1 以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上. 您也可以为多个对象指定多个变量.例如: ...

  2. Android 删除图片等资源文件 通知系统更新,重新扫描

    public void delPic(String path){ File delFile = new File(path); if (delFile.exists()) { delFile.dele ...

  3. mvc Model验证总结及常用正则表达式

    本文属转载,来源: http://www.byywee.com/page/M0/S868/868615.html 关于Model验证官方资料: http://msdn.microsoft.com/zh ...

  4. ubantu-vim操作

    vim其实就是vi的升级版,vi里的所有命令vim里都可以用,一般使用来说几乎没什么差别. 注:本篇文章区分大小写! vi / vim三级模式的关系: 命令行模式 任何时候,不管用户处于何种模式,只要 ...

  5. 如何将 gitbook上的开源书转换为mobi

    看更新后的gitbook官网说不支持pdf.mobi导出,还以为用gitbook-cli也没法导出.几轮尝试之后发现还是能导出的,使用gitbook-cli即可实现. 按如下步骤进行操作,未能完成导出 ...

  6. mysql取差集、交集、并集

    mysql取差集.交集.并集 博客分类: Mysql数据库 需求:从两个不同的结果集(一个是子集,一个是父集),字段为电话号码phone_number,找出父集中缺少的电话号码,以明确用户身份. 结合 ...

  7. 计数SQL,查找单据总量和按季度查找单据总量

    --查找单据总量 select COUNT(1) as '表XXXXXX数据量' from XXXXXXwith(nolock) --按季度查找单据总量 select count(1) as '表XX ...

  8. pytorch基础教程2

    1. 四部曲 1)forward; 2) 计算误差 :3)backward; 4) 更新 eg: 1)outputs = net(inputs) 2)loss = criterion(outputs, ...

  9. 大一下第2次作业(markdown改)

    一.作业 6-7 删除字符串中数字字符 1.设计思路 (1)主要描述题目算法 第一步:用for循环和if语句,一个一个字符判断,找到数字字符就跳过去判断下一个,否则使指针指向不是(已判断过的)数字字符 ...

  10. Dalvik源码阅读笔记(一)

    dalvik 虚拟机启动入口在 JNI_CreateJavaVM(), 在进行完 JNIEnv 等环境设置后,调用 dvmStartup() 函数进行真正的 DVM 初始化. jint JNI_Cre ...