【Spring:FactoryBean接口】实现FactoryBean接口,Spring在初始化bean时有何不同

来源:互联网 发布:天猫总是提示网络异常 编辑:程序博客网 时间:2024/06/01 08:04

问题描述:

最近想要再次熟悉一下阿里中间件HSF的用法,在消费HSF时需要在Spring的配置文件中进行如下配置:

<bean id="myClassB" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean">   <property name="interfaceName">      <value>com.lican.Myclass</value>   </property>   <property name="version">      <value>${refundplatform.provide.service.version}</value>   </property>   <property name="group">      <value>${refundplatform.hsf.provide.serviceGroup}</value>   </property></bean>

而后在代码中这样使用:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");MyClassB myClassB = (MyClassB) context.getBean("myClassB");myClassB.function();

在所有消费hsf的地方,spring的配置处,class属性均是HSFSpringConsumerBean类,可是众所周知,spring在使用如下方法:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");MyClassB myClassB = (MyClassB) context.getBean("myClassB");

进行bean的初始化时,按照class属性进行,那么为何我们将class属性设置为HSFSpringConsumerBean,却在程序中可以得到相应的服务代理类,从而进行服务的调用。后来进行资料的查阅以及HSFSpringConsumerBean类源码的阅读,发现HSFSpringConsumerBean类实现了FactoryBean接口,而实现该接口可以在Spring创建bean时实现其他类型,在HSFSpringConsumerBean类中,实际上生成的是一个实现了指定接口的代理类。实现FactoryBean接口,需要实现三个方法,看下接口FactoryBean的源码:

public interface FactoryBean<T> {     /**     * 获取实际要返回的bean对象。     * @return     * @throws Exception     */     T getObject() throws Exception;     /**     * 获取返回的对象类型     * @return     */     Class<?> getObjectType();     /**     * 是否单例     * @return     */     boolean isSingleton();  } 

自己再写一个例子实验一下:

package study20170323;import org.springframework.beans.factory.FactoryBean;/** * Created by apple on 17/3/23. */public class MyClassA implements FactoryBean {    @Override    public Object getObject() throws Exception {        MyClassB myClassB = new MyClassB();        return myClassB;    }    @Override    public Class<?> getObjectType() {        return MyClassB.class;    }    @Override    public boolean isSingleton() {        return false;    }}
package study20170323;/** * Created by apple on 17/3/23. */public class MyClassB {}
package study20170323;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * Created by apple on 17/3/23. */public class Main {    public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        MyClassB myClassB = (MyClassB) context.getBean("myClassB");        System.out.println(myClassB.getClass().getName());    }}

在spring的配置中进行如下配置:

<?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"        default-autowire="byName" default-lazy-init="true">   <bean id="myClassB" class="study20170323.MyClassA"></bean></beans>

输出结果为:

这里写图片描述

当然,如果想要直接获取FactoryBean实现类本身的实例时,可以这样写

context.getBean("&myClassB");
0 0