上一篇文章讲到BeanFactory,BeanFactory是实现spring IOC原理实现的根接口,而本篇所讲的FactoryBean则是AOP原理实现的重要接口。
本文相关代码下载地址:http://download.csdn.net/detail/sundenskyqq/8460579
1. 先看FactoryBean的源码:
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
2. 下面简单讲一下FactoryBean相关概念。
Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean,这两种Bean都被容器管理,但工厂Bean跟普通Bean不同,其返回的对象不是该factoryBean的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。如果要获取FactoryBean对象,可以在id前面加一个&符号来获取。 在Spring框架内部,有很多地方有FactoryBean的实现类,它们在很多应用如(Spring的AOP、ORM、事务管理)及与其它第三框架(ehCache)集成时都有体现。
Spring 框架中有很多FactoryBean 例如RmiProxyFactoryBean, SqlMapClientFactoryBean. LocalSessionFactoryBean等都是通过FactoryBean getObject方法驱动起来的.对bean的生产 修饰做了很好的封装。
3. 用几个例子来说明FactoryBean与普通bean的区别。
(1)普通bean
代码:
package spring.factorybean;
/**
* @author Ding Chengyun
* 2015-2-26
*/
public interface PersonService {
public String getName();
public String sayHello();
public void setName(String name);
}<pre name="code" class="java">package spring.factorybean;
/**
* @author Ding Chengyun
* 2015-2-26
*/
public class PersonServiceImpl implements PersonService {
public String name;
/* (non-Javadoc)
* @see spring.PersonService#getName()
*/
@Override
public String getName() {
return name;
}
/* (non-Javadoc)
* @see spring.PersonService#sayHello()
*/
@Override
public String sayHello() {
System.out.println("sayHello");
return "sayHello";
}
/* (non-Javadoc)
* @see spring.PersonService#setName()
*/
@Override
public void setName(String name) {
this.name = name;
}
}
配置文件
<bean id="personService" class="spring.factorybean.PersonServiceImpl">
<property name="name">
<value>hello world</value>
</property>
</bean>
测试代码:
@Test
public void test02() {
try {
PersonService ps = context.getBean("personService", PersonService.class);
ps.sayHello();
String name = ps.getName();
System.out.println(name);
} catch (Exception e) {
e.printStackTrace();
}
}
(2)FactoryBean
代码:
package spring.factorybean;
import org.springframework.beans.factory.FactoryBean;
/**
* @author Ding Chengyun
* 2015-2-27
*/
public class MyFactoryBean implements FactoryBean<MyFactoryBeanImpl> {
@Override
public MyFactoryBeanImpl getObject() throws Exception {
return new MyFactoryBeanImpl();
}
@Override
public Class<?> getObjectType() {
return MyFactoryBeanImpl.class;
}
@Override
public boolean isSingleton() {
return false;
}
}<pre name="code" class="java">package spring.factorybean;
/**
* @author Ding Chengyun
* 2015-2-27
*/
public class MyFactoryBeanImpl {
}
配置文件
<bean id="myFactoryBean" class="spring.factorybean.MyFactoryBean"></bean>
测试代码:
@Test
public void test04() {
try {
MyFactoryBeanImpl bean = context.getBean("myFactoryBean", MyFactoryBeanImpl.class);
System.out.println(bean);
MyFactoryBean factoryBean = context.getBean("&myFactoryBean", MyFactoryBean.class);
System.out.println(factoryBean);
bean = (MyFactoryBeanImpl) factoryBean.getObject();
System.out.println(bean);
} catch (Exception e) {
e.printStackTrace();
}
}
4. 自定义一个FactoryBean,用来代理一个对象,对该对象的所有方法做一个拦截,在方法调用前后都输出一行log.
代码:
package spring.factorybean;
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;
/**
* @author Ding Chengyun
* 2015-2-27
*/
public class MyLogFactoryBean implements FactoryBean<Object>, InitializingBean,
DisposableBean {
// 被代理对象实现的接口名(在使用Proxy时需要用到,用于决定生成的代理对象类型)
private String interfaceName;
// 被代理的对象
private Object target;
// 生成的代理对象
private Object proxyObj;
@Override
public void destroy() throws Exception {
System.out.println("distory...");
}
@Override
public void afterPropertiesSet() throws Exception {
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("method:" + method.getName());
System.out.println("Method before...");
Object result = method.invoke(target, args);
System.out.println("Method after...");
return result;
}
});
}
@Override
public Object getObject() throws Exception {
return proxyObj;
}
@Override
public Class<?> getObjectType() {
return proxyObj == null ? Object.class : proxyObj.getClass();
}
@Override
public boolean isSingleton() {
return false;
}
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
配置文件
<bean id="myLogFactoryBean" class="spring.factorybean.MyLogFactoryBean">
<property name="interfaceName" value="spring.factorybean.PersonService" />
<property name="target" ref="personService"/>
</bean>
测试代码:
@Test
public void test05() {
PersonService ps = context.getBean("myLogFactoryBean", PersonService.class);
ps.sayHello();
// String name = ps.getName();
// System.out.println(name);
}