4.3通过FactoryBean配置bean
来源:互联网 发布:梅兰商城源码 编辑:程序博客网 时间:2024/05/24 01:08
FactoryBean介绍
一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean 。在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个
org.Springframework.bean.factory.FactoryBean
的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。
FactoryBean
接口对于Spring框架来说占有重要的地位,Spring 自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。从Spring 3.0 开始,FactoryBean
开始支持泛型,即接口声明改为FactoryBean<T>
的形式:
package com.erick.d1.hello;import org.springframework.beans.factory.FactoryBean;public class StudentFacotryBean implements FactoryBean<Student>{ private String stuName; @Override public Student getObject() throws Exception { Student t = new Student(); t.setName(stuName); return t; } @Override public Class<?> getObjectType() { return Student.class; } @Override public boolean isSingleton() { return false; } //getter and setter ...}
<bean id="student" class="com.erick.d1.hello.StudentFacotryBean"> <property name="stuName" value="stu-factoryBean"/></bean>
接口中定义了3个方法
T getObject()
:返回由FactoryBean
创建的bean实例,如果isSingleton()
返回true
,则该实例会放到Spring容器中单实例缓存池中。boolean isSingleton()
:返回由FactoryBean
创建的bean实例的作用域是singleton
还是prototype
。Class<T> getObjectType()
:返回FactoryBean
创建的bean类型。
当配置文件中
<bean>
的class
属性配置的实现类是FactoryBean
时,通过getBean()
方法返回的不是FactoryBean
本身,而是FactoryBean#getObject()
方法所返回的对象,相当于FactoryBean#getObject()
代理了getBean()
方法。Spring提供的工厂Bean,大多数都是以FactoryBean作为后缀,并且大多用于生产一批具有某种特征的Bean实例。
如果希望获取
StudentFactoryBean
的实例,则需要在使用getBean(beanName)
方法时在beanName
前显示的加上&
前缀,例如getBean("&student")
。
Spring中一些FactoryBean的使用介绍
使用PropertyPathFactoryBean
获取其他Bean的属性值
PropertyPathFactoryBean
用来获取指定Bean的属性值,获得的值可以注入给其他Bean,也可以直接定义成新的Bean
下面是配置举例,使用了 “Spring简单例子”中的Student
和 Classes
类
<bean id="student" class="com.erick.hello.Student" p:age = "22" p:name = "cat"> <property name="classes"> <bean class="com.erick.hello.Classes" p:name="软件三班" p:number="333"/> </property></bean><bean id="classes" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName" value="student"/> <property name="propertyPath" value="classes"/></bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("Beans.xml");Classes classes= ctx.getBean("classes", Classes.class);Student student= ctx.getBean("student", Student.class);System.out.println(classes);System.out.println(student.getClasses());System.out.println(student.getClasses() == classes);//--> 输出//Classes{name='软件三班', number=333}//Classes{name='软件三班', number=333}//true
上面例子中通过PropertyPathFactoryBean
获取到了student
中的classes
这个bean可以单独使用,也可以注入到其他bean中。
注意: 上面配置PropertyPathFactoryBean
的bean标签中的id属性,并不是该Bean的唯一标识,
而是用于指定属性表达式的值。这种方式可以简化配置。
在上面的例子中加入下面配置:
<!-- 表示取得student实例的age属性 --><bean id="student.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
Integer age = ctx.getBean("student.age", Integer.class);System.out.println(age);//--> 输出//22
除此之外PropertyPathFactoryBean
的setPropertyPath()
还支持复合属性的形式。
即使用下面的方式可以获得班级的名称:
<bean id="classesName" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName" value="student"/> <property name="propertyPath" value="classes.name"/></bean>
注意: 可以使用<util:property-path>
来简化配置,使用该标签需要导入util:
命名空间.
<!-- 获取学生所在班级的名字 --><util:property-path id="classesName1" path="student.classes.name"/>
注意: 通过PropertyPathFactoryBean
来获取其他Bean的属性值时,必须要求该属性有相应的getter方法,
否则会抛出异常。
使用FieldRetrievingFactoryBean
获取Field值
FieldRetrievingFactoryBean
可以访问静态类的静态Field或者对象实例的Field值。
其中访问对象实例的Field在实际编程中没有什么用处,因为实际中java类的Field大多用private修饰,
并使用getter和setter来访问和修改,而FieldRetrievingFactoryBean
则要求实例Field用public修饰。
//在Classes类中增加静态域CONpublic class Classes { public static String CON = "xdd"; //...}
<bean id="con" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <!-- targetClass和targetObject选择一个配置即可。用来指定访问哪个目标类 --> <property name="targetClass" value="com.erick.hello.Classes"/> <!-- <property name="targetObject" ref="classes"/> --> <!-- 指定要访问的Field --> <property name="targetField" value="CON"/></bean>
也可以直接使用staticField指定访问哪个类的哪个静态域
<bean id="con" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="com.erick.hello.Classes.CON"/></bean>
FieldRetrievingFactoryBean
与PropertyPathFactoryBean
配置bean的id类似,也可以指定属性表达式的值。
使用该配置可以方便使用内部bean的注入。
<bean id="com.erick.hello.Classes.CON" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
注意: 可以使用<util:constant>
来简化配置,使用该标签需要导入util:
命名空间.
<util:constant static-field="com.erick.hello.Classes.CON" id="CON"/>
使用MethodInvokingFactoryBean
调用方法获取返回值
MethodInvokingFactoryBean
可以调用任意类的类方法,也可以调用任意对象的实例方法,
如果方法有返回值,则即可以将方法的返回值指定为容器的Bean,也可以将返回值注入给其他Bean.
具体的使用方式就不详细介绍了,与上面的两个工厂bean配置方式类似,只是参数不同。
总结
Spring的本质其实是通过XML配置来执行Java代码,因此几乎可以把所有的Java代码放到
Spring的配置文件中管理。
- 调用构造器创建对象,包括使用工厂方法创建对象,使用
<bean ../>
元素配置。 - 调用
setter
方法,使用<property .../>
元素配置。 - 调用
getter
方法,使用PropertyPathFactoryBean
工厂Bean 或<util:property-path .../>
元素配置。 - 获取
Field
的值,使用FieldRetrievingFactoryBean
工厂Bean 或者<util:constant .../>
元素配置。 - 调用普通方法,使用
MethodInvokingFactoryBean
工厂Bean。
注意: 虽然绝大多数java代码可以使用Spring配置,但是千万别这么做,这样过度使用XML配置,
会导致配置文件更加臃肿,难以维护,并会使得程序的可读性严重降低。
通常应该将以下两类信息放到XML中配置
- 项目升级和维护时,经常改动的信息。
- 控制项目内各个组件耦合关系的代码。
- 4.3通过FactoryBean配置bean
- Spring_12_通过 FactoryBean 配置 Bean
- Spring-11:通过FactoryBean配置Bean
- 三、通过 FactoryBean 来配置bean
- 十通过FactoryBean对Bean进行配置
- Spring中通过FactoryBean来配置bean
- Spring 通过FactoryBean来配置bean
- spring 10 bean配置-通过FactoryBean配置bean
- spring FactoryBean配置Bean
- Spring - bean配置-FactoryBean
- spring通过工厂方法和FactoryBean来配置Bean
- Spring-12,通过工厂方法和FactoryBean配置bean
- spring学习笔记十 通过factoryBean配置bean
- Spring学习笔记之通过FactoryBean配置Bean
- 【Spring】使用FactoryBean配置Bean
- Spring通过FactoryBean创建bean的实例
- 12.Spring学习笔记_通过FactoryBean配置Bean(by尚硅谷_佟刚)
- Spring框架学习(9):通过FactoryBean的方法配置bean
- 用户需求和产品发展相互促进的关系初探
- mysql 非空查询
- matlab面向对象教程【2】影讯抓取及其可视化展示(1/5)
- 戴上VR眼镜来场球赛?开启上帝视角
- Android通用标题栏组合控件
- 4.3通过FactoryBean配置bean
- 解决Mysql中删除重复记录的问题
- Unity的Htc Vive手柄按钮检测(转)
- 守护进程为什么要fork两次?
- 论文学习:在线学习算法综述
- 购物车数字加减按钮
- 自己的垃圾Treap
- 机器学习中的卷积
- VMware Workstation虚拟机克隆CentOS7 出现的网络问题解决