spring 源碼解讀與設計詳解:3 FactoryBean,springfactorybean

來源:互聯網
上載者:User

spring 源碼解讀與設計詳解:3 FactoryBean,springfactorybean

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



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.