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  回復  更多評論
            

          主站蜘蛛池模板: 镇平县| 东光县| 上犹县| 惠来县| 沽源县| 虞城县| 铜梁县| 循化| 天气| 平凉市| 玉龙| 承德县| 成都市| 鄂州市| 大名县| 日土县| 肇源县| 喜德县| 呈贡县| 岳阳县| 清镇市| 北宁市| 博爱县| 彰化县| 克东县| 自贡市| 松潘县| 尉犁县| 迁西县| 苏尼特右旗| 钟祥市| 天峨县| 花莲市| 嘉黎县| 平利县| 喀喇| 永兴县| 福鼎市| 德州市| 宝清县| 南皮县|