spring中的工厂FactoryBean
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring中的工厂FactoryBean相关的知识,希望对你有一定的参考价值。
工厂bean是Spring中的特殊Bean,工厂bean必须要实现FactoryBean接口。FaCtoryBean接口是工厂Bean的标准接口。Factorybean提供以下三个方法,
T getObject():实现该方法负责返回该工厂Bean生成的Java实例。
Class<?> getObjectType():实现该方法返回该工厂Bean生成的Java实例的实现类
boolean isSingleton():实现该方法表示工厂Bean生成的java实例是否是单利模式的。
程序通过getBean()方法获取工厂bean时,并不返回工厂bean的实例,而是获取getObject()中返回的实例。
下面看一个例子:
package com.spring.test.factorybean; import java.lang.reflect.Method; import org.springframework.beans.factory.FactoryBean; public class MyFactorybean implements FactoryBean<Object>{ private String name; public MyFactorybean(){ System.out.println("beanFactory被调用"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Object getObject() throws Exception{ if(("apple").equals(name)){ Class<?> clazz=Class.forName("com.spring.test.factorybean.iPhone"); Object obj= clazz.newInstance(); Method method = obj.getClass().getMethod("setMsg", String.class); method.invoke(obj, "iphone5s"); return obj; }else{ Class<?> clazz=Class.forName("com.spring.test.factorybean.MIPhone"); Object obj= clazz.newInstance(); Method method = obj.getClass().getMethod("setMsg", String.class); method.invoke(obj, "MI5"); return obj; } } public Class<?extends Object>getObjectType(){ return Object.class; } public boolean isSingleton(){ return false; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="apple" class="com.spring.test.factorybean.MyFactorybean"> <property name="name" value="apple"/> </bean> <bean id="xiaomi" class="com.spring.test.factorybean.MyFactorybean"> <property name="name" value="xiaomi"/> </bean> </beans>
运行结果为
每次配置bean之后都会调用factorybean的构造函数,但是构造函数中并没有返回实例。实例是在getObject的方法中被调用的。
Spring还提供了一些公有的bean,较为常见的有:
PropertyPathFactoryBean:调用getter()方法;
FieldRetreiecingFactoryBean:调用类对象的属性值;
MethodInvokingFactoryBean:调用普通方法;
(一)PropertyPathFactoryBean
PropertyPathFactoryBean获取目标bean的getter()方法注入给其他bean,也可以直接定义成新的bean。在使用PropertyPathFactoryBean调用其他的bean的时候,需要使用
SetTargetObject(Object targetObject)指定需要调用的对象。使用setPropertyPath(String propertyPath)方法指定调用哪个getter()方法。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="apple" class="com.spring.test.factorybean.iPhone"> <property name="msg" value="iphone6"/> </bean> <bean id="msg" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName" value="apple"/> <property name="propertyPath" value="msg"/> </bean> </beans>
运行结果为
msg的值为apple对象的getMsg()方法的返回值,也可以将获取getter()方法的值注入到其他的bean中例:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="apple" class="com.spring.test.factorybean.iPhone"> <property name="msg" value="iphone6"/> </bean> <!-- <bean id="msg" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName" value="apple"/> <property name="propertyPath" value="msg"/> </bean>--> <bean id="apple1" class="com.spring.test.factorybean.iPhone"> <property name="msg"> <bean id="apple.msg" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/> </property> </bean> </beans>
package com.spring.test.factorybean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class testmain { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ctx=new ClassPathXmlApplicationContext("PropertyPathFactoryean.xml"); Phone p1=(iPhone)ctx.getBean("apple"); Phone p2=(iPhone)ctx.getBean("apple1"); p2.call(); } }
从上面的例子可以看出,p2的msg属性是由p1的getMsg()方法的值注入的。
(二)FieldRetrievingFactroybean
FieldRetrievingFactroybean可以访问类的静态属性或实例属性(实例属性大多封装可已使用PropertyPathFactoryBean代替,所以此用处不多)。这里只介绍访问静态Field。
需要使用SetTargetClass(String targetClass)指定需要调用的类。使用setTargetField(String targetField)方法指定访问的类静态属性。用法与上述代码相似这里就不一一举例了。FieldRetrievingFactroybean 还提供了setStaticFField(String staticField)方法可一直接调用类的静态属性。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="apple" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="apple.msg"/> </bean> </beans>
以上是关于spring中的工厂FactoryBean的主要内容,如果未能解决你的问题,请参考以下文章
Spring5学习笔记 — “工厂Bean(FactoryBean)”
《Spring揭秘》---- 工厂方法与FactoryBean