ALL is Well!

          敏捷是一條很長的路,摸索著前進著

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks
          通過上一篇 利用自定義Java注解實現資源注入 介紹的方法,我們實現了通過自定義注解完成了對DataSource資源的注入,但在實際應用中,我們通常不希望去顯式的去聲明這樣的MyAnnotationBeanProcessor對象來幫助我們完成注入,而是希望通過Spring幫我們“悄悄地”完成。
          利用自定義Java注解實現資源注入 里的代碼(部分代碼)不變,我們希望在測試類中以如下方法調用便可以實現資源的注入:
          import org.springframework.context.support.ClassPathXmlApplicationContext;

          import com.annotation.MyService;

          public class SpringWiringTest {
              
          public static void main(String args[]) {
                  ClassPathXmlApplicationContext ctx 
          = new ClassPathXmlApplicationContext("com/spring/applicationContext.xml");
                  MyService b 
          = (MyService)ctx.getBean("myService"); // 通過Spring去管理bean,此時已完成了對標有DataSource注解的資源的注入
                  System.out.println(b.selectForObjectFromB(""null));
                  System.out.println(b.selectForObjectFromA(
          ""null));
              }

          }

          注:MyService類實現在 利用自定義Java注解實現資源注入 中。

          為了實現上面的目標,我們就不能使用MyAnnotationBeanProcessor.java類來實現對資源的注入了,我們必須實現一個能融入Spring的BeanProcessor類才行。
          DataSourceBeanProcessor.java類實現BeanPostProcessor、PriorityOrdered接口:
          import java.lang.reflect.Field;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.factory.config.BeanPostProcessor;
          import org.springframework.core.Ordered;
          import org.springframework.core.PriorityOrdered;

          public class DataSourceBeanProcessor implements BeanPostProcessor, PriorityOrdered {
              @Override
              
          // 在這里完成資源注入
              public Object postProcessAfterInitialization(Object bean, String beanName)
                  
          throws BeansException {
                  Class
          <?> cls = bean.getClass();
                  
          for (Field field : cls.getDeclaredFields()) {
                      
          if (field.isAnnotationPresent(DataSource.class)) {
                          DataSourceStaticWiring.wiring(bean, field);
                      }

                  }

                  
          return bean;
              }


              @Override
              
          public Object postProcessBeforeInitialization(Object bean, String beanName)
                  
          throws BeansException {
                  
          return bean;
              }


              @Override
              
          public int getOrder() {
                  
          return Ordered.LOWEST_PRECEDENCE;
              }

          }

          下面來看DataSourceStaticWiring的實現,與前一篇 里的DataSourceWiring.java類相比,改動點有以下三個:
          1.不需要實現IFieldWiring接口
          2.刪除annotationClass方法
          3.將wiring方法修改為static方法
          具體代碼如下:
          import java.lang.reflect.Field;

          public class DataSourceStaticWiring {

              
          public static void wiring(Object object, Field field) {
                  Object fieldObj 
          = ReflectUtils.getFieldValue(object, field.getName());
                  
          if (fieldObj != null{
                      
          return;
                  }

                  DataSource annotation 
          = field.getAnnotation(DataSource.class);
                  String type 
          = annotation.type();
                  String sqlMap 
          = annotation.sqlMap();
                  
          // 這里可以用緩存來實現,不用每次都去創建新的SqlMapClient對象
                  SqlMapClient sqlMapImpl = new SqlMapClient(sqlMap, type);
                  ReflectUtils.setFieldValue(object, field.getName(), SqlMapClient.
          class, sqlMapImpl);
              }

          }

          注:SqlMapClient、ReflectUtils實現在上一篇 利用自定義Java注解實現資源注入 中。

          代碼已準備就緒,接下來是配置Spring:applicationContext.xml
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:aop
          ="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
              xmlns:context
          ="http://www.springframework.org/schema/context"
              xsi:schemaLocation
          ="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                  http://www.springframework.org/schema/aop 
                                  http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                                  http://www.springframework.org/schema/tx 
                                  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                                  http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-2.5.xsd"

              default-lazy-init
          ="true">
              
              
          <!-- 自定義的BeanProcessor -->
              
          <bean class="com.annotation.DataSourceBeanProcessor" />
              
          <context:component-scan base-package="com.annotation" />

              
          <!-- 測試用bean -->
              
          <bean id="myService" class="com.annotation.MyService" destroy-method="close">
              
          </bean>
          </beans>

          測試代碼其實已經在前面列出來了。SpringWiringTest.java
          import org.springframework.context.support.ClassPathXmlApplicationContext;

          import com.annotation.MyService;

          public class SpringWiringTest {
              
          public static void main(String args[]) {
                  ClassPathXmlApplicationContext ctx 
          = new ClassPathXmlApplicationContext("com/spring/applicationContext.xml");
                  MyService b 
          = (MyService)ctx.getBean("myService");
                  System.out.println(b.selectForObjectFromB(
          ""null));
                  System.out.println(b.selectForObjectFromA(
          ""null));
              }

          }

          執行結果:
          SqlMapClient[sqlMap=com/annotation/sql-map-config-B.xml,type=B]
          SqlMapClient[sqlMap
          =com/annotation/sql-map-config-A.xml,type=A]

          由結果可見,我們利用Spring完成了對DataSource資源的注入了。

          在這里如果還想擴展的話,就需要新建類假設為InParamBeanProcessor,實現BeanPostProcessor、PriorityOrdered接口,然后實現其中的方法,對資源進行注入,這里就是擴展Spring了,與本篇介紹的方法相同。

          注:以上代碼重在演示,其實這個需求可以在Spring中管理兩個不同的SqlMapClient對象,然后通過Spring的自動注入實現。

          本文為原創,歡迎轉載,轉載請注明出處BlogJava
          posted on 2010-10-04 10:31 李 明 閱讀(8239) 評論(1)  編輯  收藏 所屬分類: JavaSpring

          評論

          # re: 通過Spring實現對自定義注解屬性進行資源注入 2016-05-10 18:28 如煩人煩人
          ffhty  回復  更多評論
            

          主站蜘蛛池模板: 仁寿县| 会昌县| 罗田县| 南丹县| 洪泽县| 囊谦县| 五河县| 平度市| 油尖旺区| 长乐市| 五莲县| 微山县| 监利县| 湖北省| 东兰县| 阳谷县| 鸡泽县| 甘谷县| 乳山市| 如东县| 华蓥市| 卢氏县| 基隆市| 汉川市| 高阳县| 驻马店市| 邯郸市| 德庆县| 天气| 寻乌县| 镇巴县| 永吉县| 新泰市| 渝中区| 泊头市| 滦平县| 阿拉善盟| 太和县| 青岛市| 通州市| 南通市|