spring 源码解读与设计详解:3 FactoryBean

来源:互联网 发布:淘宝刷真实无线流量 编辑:程序博客网 时间:2024/05/17 00:11

上一篇文章讲到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() */@Overridepublic String getName() {return name;}/* (non-Javadoc) * @see spring.PersonService#sayHello() */@Overridepublic String sayHello() {System.out.println("sayHello");return "sayHello";}/* (non-Javadoc) * @see spring.PersonService#setName() */@Overridepublic 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> {@Overridepublic MyFactoryBeanImpl getObject() throws Exception {return new MyFactoryBeanImpl();}@Overridepublic Class<?> getObjectType() {return MyFactoryBeanImpl.class;}@Overridepublic 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;      @Overridepublic void destroy() throws Exception { System.out.println("distory...");  }@Overridepublic 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;}});}@Overridepublic Object getObject() throws Exception {        return proxyObj; }@Overridepublic Class<?> getObjectType() {return proxyObj == null ? Object.class : proxyObj.getClass();  }@Overridepublic 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);   }   



0 0
原创粉丝点击