标签:
上一篇文章讲到BeanFactory,BeanFactory是实现spring IOC原理实现的根接口,而本篇所讲的FactoryBean则是AOP原理实现的重要接口。
1. 先看FactoryBean的源码:
public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton(); }
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(); } }
代码:
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); }
spring 源码解读与设计详解:3 FactoryBean
标签:
原文地址:http://blog.csdn.net/sundenskyqq/article/details/43966517