spring 之 factory-bean & factory-method
这两者常常是一起出现的,或者说他们经常是一起被使用的。但是其实是分为了两种情况:
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的更多相关文章
- Spring 通过工厂方法(Factory Method)来配置bean
Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...
- 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 ...
- 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 ...
- Spring系列之bean的使用
一.Bean的定义 <bean id="userDao" class="com.dev.spring.simple.MemoryUserDao"/> ...
- Spring IOC之Bean 概述
1.Bean概述 一个Spring IOC容器管理一个或者多个bean.这些bean是根据你提供给容器的配置数据信息创建的,例如XML形式的的定义. 在容器内部,这些bean的定义表示为BeanDef ...
- Spring读书笔记——bean加载
我们的日常开发几乎离不开Spring,他为我们的开发带来了很大的便捷,那么Spring框架是如何做到方便他人的呢.今天就来说说bean如何被加载加载. 我们在xml文件中写过太多类似这样的bean声明 ...
- Spring读书笔记——bean创建(上)
通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...
- Spring高级装配bean
目录 spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 一.环境与profile 配置profile bean 在软件开发的时候,有一个 ...
- spring(二、bean生命周期、用到的设计模式、常用注解)
spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...
- spring AbstractBeanDefinition创建bean类型是动态代理类的方式
1.接口 Class<?> resourceClass 2.获取builder BeanDefinitionBuilder builder = BeanDefinitionBuilder. ...
随机推荐
- linux 服务器之间配置免密登录
客户机:172.16.1.2 远程机:172.16.1.3 1.远程机 a.允许root用户通过22端口登录 vi /etc/ssh/sshd_config PORT 22 PermitRootLog ...
- ubuntu-docker入门到放弃(四)容器的导入导出
上一次我们讲了如何搭建自己私有的镜像管理仓库,实际上我们使用的依然是别人或者公共的image,今天就来说说如何将自己定制化的images上传到自己的私有仓库中,以供符合自己业务场景的项目来使用,如:我 ...
- 【巷子】---middleware---redux-promise-middleware---【react】
一.Middleware的由来 单一的state是存储在store中,当要对state进行更新的时候,首先要发起一个action(通过dispatch函数),action的作用就是相当于一个消息通知, ...
- C++进阶--静态初始化的惨败
/* Initialization Fiasco 一个会使程序崩溃的细微的问题 */ // 不同文件的编译顺序是不确定的 // 如果一个文件依赖另一个文件的对象先初始化,可能出现问题 // 解决方法: ...
- 【事务隔离级别】数据库事务隔离级别-UNDERSTANDING ISOLATION LEVELS
参考链接:ISOLATION LEVELS ISOLATION LEVELS In a database system, concurrent transactions are processed i ...
- webpack学习总结(一)
* webpack安装 1. 安装最新node,node自带npm包管理器: 2. 全局模式安装webpack(只有将webpack在全局模式下安装才能在命令行直接通过webpack执行命令) $np ...
- PAT 乙级 1008 数组元素循环右移问题 (20) C++版
1008. 数组元素循环右移问题 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 一个数组A中存有N(N>0)个整数,在不允 ...
- NFS应用场景及环境搭建
两台虚拟机,一台做服务端(server)用来存储,一台做客户端(client)用来访问. 注意,两台虚拟机都已经挂载完光盘,并配置好yum源.客户端client已经安装好lamp环境,服务端不做任何处 ...
- [UE4]工程设置:自动捕获鼠标、通过代码设置鼠标显示隐藏、输入模式、编译时自动保存
一.在4.20版本中运行游戏,在没有进行任何设置的情况下,游戏不会自动捕获鼠标,游戏不会接受输入,需要手动点一下游戏界面才行.如果要跟老版本一样运行游戏自动捕获鼠标,需要进行设置 二.也可以通过代码的 ...
- vue 动态路由 Get传值
main.js //2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', compone ...