Spring中基于FactoryBean的练习
- 1.BeanFactory,
以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。 - 2.FactoryBean
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获
取FactoryBean对象,请在id前面加一个&符号来获取。
请参考如下代码:
//ABean.java
package sping.analysis.beans;
public class ABean implements MyBean {
private String name;
public ABean(String name) {
this.name = name;
}
public void doSomething() {
System.out.println(this.name);
}
}
//MyBean.java
package sping.analysis.beans;
public interface MyBean {
void doSomething();
}
//MyFactoryBean.java
package sping.analysis.beans;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean {
@Value(value = "sping.analysis.beans.MyBean")
private String interfaceName;
@Autowired(required=false) @Qualifier("aBean")
private Object target;
private Object proxyObj;
public void destroy() throws Exception {
System.out.println(this.getClass().getName() + ".destroy() ....");
}
/** * 注意: * JDK Proxy 动态代理是基于 接口 来实现的。 * cglib 才是基于类实现的 */
public void afterPropertiesSet() throws Exception {
System.out.println(this.getClass().getName() + ".afterPropertiesSet() ...");
proxyObj = Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[] { Class.forName(interfaceName)},
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke method:" + method.getName());
Object res = method.invoke(target, args);
return res;
}
});
}
public Object getObject() throws Exception {
System.out.println(this.getClass().getName() + ".getObject() ...");
return proxyObj;
}
public Class<?> getObjectType() {
return proxyObj == null ? Object.class : proxyObj.getClass();
}
}
//TestFactoryBean.java
package sping.analysis.beans;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application3.xml")
public class TestFactoryBean {
@Resource(name = "myFactoryBean")
private MyBean myBean;
//如果要获取FactoryBean对象,请在id前面加一个&符号来获取
@Resource(name = "&myFactoryBean")
private MyFactoryBean myFactoryBean;
@Test
public void test() {
myBean.doSomething();
System.out.println("> myFactoryBean.isSingleton:" + myFactoryBean.isSingleton());
}
}
输出结果:
sping.analysis.beans.MyFactoryBean.afterPropertiesSet() ...
sping.analysis.beans.MyFactoryBean.getObject() ...
invoke method:doSomething
张三
> myFactoryBean.isSingleton:true
sping.analysis.beans.MyFactoryBean.destroy() ....
//application3.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="sping.analysis.beans"/>
<bean id="aBean" class="sping.analysis.beans.ABean">
<constructor-arg type="java.lang.String" value="张三" />
</bean>
</beans>
还没有评论,来说两句吧...