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

上一篇文章讲到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);  
	 }  
	 



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值