这两者常常是一起出现的,或者说他们经常是一起被使用的。但是其实是分为了两种情况:

1 同时使用factory-bean 和 factory-method

如果,我们在一个bean 元素上同时配置 factory-bean 和 factory-method, 那么意思就是说, 这个bean 的创建就使用工厂模式吧, 工厂模式的创建者, 也就是主体bean 是 factory-method 指向的 bean, 而 工厂方法呢? 就是 factory-method。  不过呢, 这里有个要求, 工厂类的  factory-method 方法必须是非静态的, 而且必须要返回 当前bean 的实例对象。 但是它可以是 private 方法。

这个其实很好理解:

factory-method 方法必须是非静态的—— 如果是静态的,那么我们就不需要多此一举引用factory-bean 的实例了吧, 再就是static工厂方法,也不需要spring 来管理了吧! 直接 XxxFactory.getYyy(), 这样的方式不就好了吗?

如果是静态的,则出现异常:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'boss' defined in class path resource [beans.xml]: No matching factory method found: factory bean 'man'; factory method 'fmm(String)'. Check that a method with the specified name and arguments exists and that it is non-static.
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory$.getObject(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:)
at AnnoIoCTest.main(AnnoIoCTest.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:)

必须要返回 当前bean 的实例对象—— 如果不是返回 一个bean实例, 那还算是哪门子的 工厂方法?

还有, 如果我们在一个bean 元素上同时配置 factory-bean 和 factory-method,那么bean的 class 属性是可以省去的, 那么bean 的类型呢? factory-method 返回什么就是什么, 返回 String, int  也是可以的!

另外, 工厂方法是可以有参数的, 如果有参数,那么 我们需要通过  bean 元素的 子元素 constructor-arg 进行配置。原理跟 普通的 构造方法注入是一样的。 不过呢, 这个constructor-arg 是 factory-bean 进行调用 以及注入的, 不是spring  IoC 注入的。

    <bean id="boss"  init-method="initBoss" lazy-init="true" destroy-method="destro"
factory-method="fmm"
factory-bean="man"
>
<constructor-arg value=""></constructor-arg>
</bean> <bean id="man" class="com.baobaotao.Man" dependency-check="none" scope="prototype" lazy-init="true"/>

2 单独使用 当前类的静态方法: factory-method 。 也就是只配置了 factory-method, 没有配置  factory-bean

这两种情况是很大差别的!!

如果单独使用  factory-method, 那么这个 factory-method 必须是 当前class 的静态方法。 试想, 如果不是静态方法,又要使用工厂方法, 又要通过spring 来创建bean, 那么就 太矛盾了吧!

前面我们说 “ 直接 XxxFactory.getYyy(), 这样的方式不就好了吗”,其实这个说法也是不太准确的。  那么 这个时候,通过单独使用  factory-method 静态方法的意义呢?  我想, 大概在于我们可以给 静态 工厂方法注入一些 参数, 以用来构造 我们的bean 吧!  这个正是spring 的灵活之处。

spring 之 factory-bean & factory-method的更多相关文章

  1. Spring 通过工厂方法(Factory Method)来配置bean

    Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...

  2. Error creating bean with name 'mapper' defined in class path resource [applicationcontext.xml]: Cannot resolve reference to bean 'factory' while setting bean property 'sqlSessionFactory'; nested excep

    Error creating bean with name 'mapper' defined in class path resource [applicationcontext.xml]: Cann ...

  3. Simple Factory vs. Factory Method vs. Abstract Factory【简单工厂,工厂方法以及抽象工厂的比较】

    I ran into a question on stackoverflow the other day that sort of shocked me. It was a piece of code ...

  4. Spring系列之bean的使用

    一.Bean的定义 <bean id="userDao" class="com.dev.spring.simple.MemoryUserDao"/> ...

  5. Spring IOC之Bean 概述

    1.Bean概述 一个Spring IOC容器管理一个或者多个bean.这些bean是根据你提供给容器的配置数据信息创建的,例如XML形式的的定义. 在容器内部,这些bean的定义表示为BeanDef ...

  6. Spring读书笔记——bean加载

    我们的日常开发几乎离不开Spring,他为我们的开发带来了很大的便捷,那么Spring框架是如何做到方便他人的呢.今天就来说说bean如何被加载加载. 我们在xml文件中写过太多类似这样的bean声明 ...

  7. Spring读书笔记——bean创建(上)

    通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...

  8. Spring高级装配bean

    目录 spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 一.环境与profile 配置profile  bean 在软件开发的时候,有一个 ...

  9. spring(二、bean生命周期、用到的设计模式、常用注解)

    spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...

  10. spring AbstractBeanDefinition创建bean类型是动态代理类的方式

    1.接口 Class<?> resourceClass 2.获取builder BeanDefinitionBuilder builder = BeanDefinitionBuilder. ...

随机推荐

  1. 深入理解 JavaScript 中的函数

    JavaScript函数也具有这些特性,但它们不仅仅是常规函数.JavaScript函数是对象.你可以查看我曾经写的关于JavaScript对象的文章,里面我提到几乎JavaScript中的所有一切都 ...

  2. CentOS 7.4 初次手记:第二章 CentOS安装步骤

    第二章 CentOS安装步骤... 18 第一节 下载... 18 第二节 分区参考... 18 第三节 安装... 19 I Step 1:引导... 19 II Step 2:配置... 20 I ...

  3. SpringBoot之退出服务(exit)时调用自定义的销毁方法

    我们在工作中有时候可能会遇到这样场景,需要在退出容器的时候执行某些操作.SpringBoot中有两种方法可以供我们来选择(其实就是spring中我们常用的方式.只是destory-method是在XM ...

  4. 三星GT-N8010刷机教程

    本刷机教程只针对三星GT-N8010机器(以下简称GT-N8010),以下操作本人已在GT-N8010机器上亲测,且都成功,其它机器没有测试不能保证成功. 刷机有风险,请谨慎使用!请先备份资料和信息. ...

  5. BloomFilter理解

    知道BloomFilter是因为RocksDB数据库中用到了这个技术,用于判断1个数据是否存在于1个SST文件中. BloomFilter可能存在误判,就是判断数据是存在集合中,而实际上可能不存在,概 ...

  6. openVPN设置本地密码验证

    wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh https://github.com/ ...

  7. 去中心化存储的QoS是什么?

    我的前面一篇文章讲到如何做去中化存储,文其中提到了QoS (Quality of Service),那么QoS是什么?为什么QoS那么重要?下面将详细描述. 什么是QoS? 提到QoS,就要先了解Qo ...

  8. [UE4]AWP狙击枪开镜

    一.使用一张PNG图片,中间是透明的,其他部分是纯黑色.创建一个UserWidget.作为AWP的开镜后的准心.AWP默认状态下是没有准心的. 二.右键开镜.把第一步创建的UserWidget创建出来 ...

  9. mysql为什么要分库分表?

    1 基本思想之什么是分库分表?从字面上简单理解,就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上. 2 基本思想之为什么要分库分表? 单表操作数据量有最优值, ...

  10. HTTP RFC解析

    HTTP协议(HyperText Transfer Protocol,超文本传输协议)HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出, ...