问题描述:
最近想要再次熟悉一下阿里中间件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");