niubtangno1ID:niubtangno1
5141次访问,排名17351(-8)好友0人,关注者0
niubtangno1的文章
原创 19 篇
翻译 0 篇
转载 3 篇
评论 0 篇
最近评论
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      转载 Spring2之Lookup Method Injection(查找方法注入) 收藏

      新一篇: python get,post提交表单 | 旧一篇: 日期计算

      package ch5.LookupMethod;

      public interface DemoBean ...{
        public MyHelper getmyHelper();
        public void someOperation();
      }

      Spring使用CGLIB的动态字节码增强功能,所以,必须要加入CGLIB包

      当Bean依赖另一个生命周期不同的bean,尤其是当singleton依赖一个non-singleton时,常会遇到不少问题,Lookup Method Injection正是对付这些问题而出现的,在上述情况中,setter和构造注入都回导致singleton去维护一个non-singleton bean的单个实例,某些情况下,我们希望让singleton bean每次要求获得bean时候都返回一个non-singleton bean的新实例

      Myhelper Bean


      package ch5.LookupMethod;

      public class MyHelper ...{
        public void doSomething()...{
          
        }
      }


      以下是两个singleton bean的实现接口

       

      package ch5.LookupMethod;

      public interface DemoBean ...{
        public MyHelper getmyHelper();
        public void someOperation();
      }

       

      以下代码是StandardLookupDemoBean使用setter方式获得MyHelper bean

       

      package ch5.LookupMethod;

      public class StandardLookupDemoBean implements DemoBean ...{
          private MyHelper myHelper;
          public void setMyHelper(MyHelper myHelper) ...{
              this.myHelper = myHelper;
          }
          public MyHelper getmyHelper() ...{   
              return this.myHelper;
          }
          public void someOperation() ...{
              myHelper.doSomething();
          }

      }


      以下是使用Lookup Method的abstract class

      之所以定义成抽象类,后面会有论述

      package ch5.LookupMethod;

      public abstract class AbstractLoopipMethodDemoBean implements DemoBean ...{

         
          public abstract MyHelper getmyHelper();
          public void someOperation() ...{
              getmyHelper().doSomething();
          }

      }

       

      配置文件:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <beans
          xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">


      <bean id="helper" class="ch5.LookupMethod.MyHelper" scope="prototype"> <!-- spring2.0使用scope="singleton/prototype代替singleton="true/false" -->
      </bean>

      <bean id="standardBean" class="ch5.LookupMethod.StandardLookupDemoBean">
       <property name="myHelper">
         <ref local="helper"/>
       </property>
      </bean>

      <bean id="abstractBean" class="ch5.LookupMethod.AbstractLoopipMethodDemoBean">
        <lookup-method name="getmyHelper" bean="helper"/>
      </bean>


      </beans>
       

      测试代码:

       

      package ch5.LookupMethod;

      import java.io.File;

      import org.springframework.beans.factory.BeanFactory;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.xml.XmlBeanFactory;
      import org.springframework.core.io.FileSystemResource;
      import org.springframework.util.StopWatch;

      public class TestSpring...{
        public static void main(String args[])  throws Exception...{
            //获取bean factory
            ConfigurableListableBeanFactory factory=(ConfigurableListableBeanFactory)getBeanFactory();  //使用子beanFactory
          
          
            DemoBean standardBean=(DemoBean)factory.getBean("standardBean");
            DemoBean abstractBean=(DemoBean)factory.getBean("abstractBean");

            displayInfo(standardBean);
            displayInfo(abstractBean);
        }
        public static BeanFactory getBeanFactory()...{
            //获取bean factory
            String realpath="";
        
               //加载配置项
            realpath=System.getProperty("user.dir")+File.separator+"src"+File.separator+"ch5/LookupMethod"+File.separator+"applicationContext.xml";
       
          
            ConfigurableListableBeanFactory  factory=new XmlBeanFactory(new FileSystemResource(realpath));
           
            return factory;
        }
       
        public static void displayInfo(DemoBean bean)...{
            MyHelper helper1=bean.getmyHelper();
            MyHelper helper2=bean.getmyHelper();
            System.out.println("Helper instance the same:"+(helper1==helper2));
           
            StopWatch stopWatch=new StopWatch();
            stopWatch.start("TestSpring");
            for (int i = 0; i < 1000000; i++) ...{
                MyHelper helper=bean.getmyHelper();
                helper.doSomething();
            }
            stopWatch.stop();
            System.out.println(stopWatch.getTotalTimeMillis());
        }
      }

       

      结果:

      Helper instance the same:true
      16
      Helper instance the same:false
      3594


      结果说明:

      对于StandardLookupDemoBean,单个MyHelper实例通过setter注入,且这个实例保存下来,所以为true
      对于AbstractLoopipMethodDemoBean,每次调用getMyHelper()时候都会返回新实例,所以为false
      StopWatch是spring提供的一个测试程序效率的工具类

      注意事项:

      1.应用场合:需要处理两个生命周期不同的bean时候使用
      2.假定你有三个singleton,公用一个依赖,希望每个singleton有自己的实例依赖,所以将依赖设置成singleton,但
         实际上每个singleton在其生命周期中使用协作着的同一个实例足以,这种情况下,setter是最好的选择,使用方
         法查找注入会增加不必要的开销
      3.我们也可以使用实现BeanFactoryAware的方式代替Lookup Method Injection

          public void setBeanFactory(Beanfactory factory){
               this.factory=factory;
         }
         public MyHelper getMyHelper(){
            return (MyHelper)factory.getBean("helper");
         }

         使用上述方法在效率上和使用本例的方法,相差无几(100000次差别在几毫秒),所以,建议使用本里的方法,减少和spring api的耦合

      4.尽管可以不把查找方法定义成abstract,但还是建议这样做,可以防止不小心忘了配置查找方法而留一个空方法在代码中

       

      发表于 @ 2008年01月10日 15:10:00|编辑

      新一篇: python get,post提交表单 | 旧一篇: 日期计算

      评论:没有评论。

      Csdn Blog version 3.1a
      Copyright © 神の熊猫