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>
时间: 2024-08-14 17:36:54

spring中的工厂(二)FactoryBean的相关文章

Spring学习笔记——Spring中的BeanFactory与FactoryBean

BeanFactory BeanFactory是Spring的org.springframework.beans.factory下的一个接口,是Spring IOC所遵守的基本编程规范,他的实现类有DefaultListableBeanFactory.XmlBeanFactory.ApplicationContext等,都各自实现自己的功能. FactoryBean 通常Spring通过反射机制利用bean的class属性来指定实现类的实例化Bean,在某些情况下实例化Bean的过程比较复杂,如

spring中的工厂原理简单模拟

package service; import dao.User;import factory.Factory; public class Test {// private static User user = new UserImpl();//耦合度太高 private static User user = (User) Factory.getIntence().getBean("userdao");public static void main(String[] args) {us

聊聊Spring中的工厂

BeanFactory是Spring IOC容器的根接口,定义了Bean工厂的最基础的功能特性,比如根据name获取指定bean等,根据不同用途它的子接口又对它的功能进行细化,比如是否是可列表的,是否是有层次关系的,是否拥有自动装配能力等.它最常用的实现类DefaultListableBeanFactory,它直接或通过继承间接实现了上述接口的所有功能,并被ApplicationConext的实现类持有,实例化为运行中的IOC容器(一系列可能有相互依赖关系的Bean集合). FactoryBea

Spring中的DataBinding(二) - Validation

@Controller@RequestMapping(value = "/custom/register")public class RegistrationController { // Set the data binding per controller @InitBinder public void initBinder(WebDataBinder binder){ binder.setDisallowedFields("id"); // 此处指定在绑定的时

Spring中的BeanFactory和FactoryBean的区别

一句话介绍 BeanFactory接口用来生产Bean,它处理生产bean的接口体系的最顶层,getBean方法可以获取bean.FactoryBean接口用来定制Bean的生产过程,getObject方法中可以实现自定义过程. 源码 BeanFactory源码 public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansExce

Spring中FactoryBean的作用和实现原理

BeanFactory与FactoryBean,相信很多刚翻看Spring源码的同学跟我一样很好奇这俩货怎么长得这么像,分别都是干啥用的.BeanFactory是Spring中Bean工厂的顶层接口,也是我们常说的SpringIOC容器,它定下了IOC容器的一些规范和常用方法并管理着Spring中所有的Bean,今天我们不讲它,我们看一下后面那个FactoryBean. 先说下FactoryBean和其作用再开始分析:首先它是一个Bean,但又不仅仅是一个Bean.它是一个能生产或修饰对象生成的

Spring详解(二)------IOC控制反转

我相信提到 Spring,很多人会脱口而出IOC(控制反转).DI(依赖注入).AOP等等概念,这些概念也是面试官经常问到的知识点.那么这篇博客我们就来详细的讲解 IOC控制反转. ps:本篇博客源码下载链接:http://pan.baidu.com/s/1miwZIf2 密码:oquc 1.什么是 IOC? IOC-Inversion of Control,即控制反转.它不是什么技术,而是一种设计思想. 传统的创建对象的方法是直接通过 new 关键字,而 spring 则是通过 IOC 容器来

看完这篇你还敢说,不懂Spring中的IoC容器?

一. 什么是IoC 什么是耦合和内聚 耦合指的就是模块之间的依赖关系.模块间的依赖越多,则表示耦合度越高,相应的维护成本就越高.内聚指的是模块内功能之间的联系.模块内功能的联系越紧密,则表示内聚度越高,模块的职责也就越单一.所以在程序开发中应该尽量的降低耦合,提高内聚.也就是设计原则中的开闭原则和单一职责原则. 工厂模式 工厂模式就是用来解决程序间耦合的一种设计模式.可以把所有要创建的对象放在工厂的一个集合里,当需要使用这个对象的时候,直接从工厂里面取出来用就行. 工厂模式的优点: 一个调用者想

Spring中BeanFactory与FactoryBean的区别

在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean().containsBean()等管理Bean的通用方法.Spring的容器都是它的具体实现如: DefaultListableBeanFactory XmlBeanFactory ApplicationContext 这些实现类又从