Never give up!

          如果說軟件開發(fā)是一條布滿荊棘的坎坷之路,那么我會每天在這道路兩旁書上“火焰舞者,到此一游!”。

           

          Inject Bean By Annotation

          Spring IoC容器允許BeanFactoryPostProcessor在容器實際實例化任何其它的bean之前讀取配置元數(shù)據(jù),并有可能修改它。本文就是以annotation的方式對bean進行依賴注入。

          代碼如下:
          Annotation

          import java.lang.annotation.Inherited;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          import static java.lang.annotation.ElementType.METHOD;
          import static java.lang.annotation.ElementType.FIELD;

          @Target(
          {METHOD, FIELD})
          @Retention(RetentionPolicy.RUNTIME)
          @Inherited
          public @interface Inject {
              
          // 默認(rèn)注入方式是byName
              String value() default "";
          }

          BeanFactoryPostProcessor

          import java.beans.PropertyDescriptor;
          import java.lang.reflect.Method;

          import org.springframework.beans.BeanUtils;
          import org.springframework.beans.BeansException;
          import org.springframework.beans.MutablePropertyValues;
          import org.springframework.beans.PropertyValue;
          import org.springframework.beans.factory.CannotLoadBeanClassException;
          import org.springframework.beans.factory.config.BeanDefinition;
          import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
          import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
          import org.springframework.beans.factory.config.RuntimeBeanReference;
          import org.springframework.core.annotation.AnnotationUtils;
          import org.springframework.util.StringUtils;

          public class InjectProcessor implements BeanFactoryPostProcessor {

              
          public void postProcessBeanFactory(
                      ConfigurableListableBeanFactory configurablelistablebeanfactory)
                      
          throws BeansException {
                  
                  String[] beanDefinitionNames 
          = configurablelistablebeanfactory.getBeanDefinitionNames();
                  
                  BeanDefinition beanDefinition 
          = null;
                  MutablePropertyValues propertyValues 
          = null;
                  Method method 
          = null;
                  Inject inject 
          = null;
                  String propertyName 
          = null;
                  
                  
          for (String beanDefinitionName : beanDefinitionNames) {
                      beanDefinition 
          = configurablelistablebeanfactory.getBeanDefinition(beanDefinitionName);
                      
                      
          if (beanDefinition.isAbstract())
                          
          continue;
                      
                      
          // 返回指定Bean定義信息的屬性集合,此集合在bean factory post-processing期間可以被修改?
                      propertyValues = beanDefinition.getPropertyValues();
                      
                      
          /*
                       * 找回指定類的屬?性?描述(PropertyDescriptor)列表
                       * PropertyDescriptor主要描述?一個屬性和此屬性的?一對訪問方?法(getter and setter)
                       
          */

                      
          for (PropertyDescriptor descriptor : BeanUtils.getPropertyDescriptors(
                              getBeanClassByName(beanDefinitionName, beanDefinition))) 
          {
                          
          // 屬?性?集合中已經(jīng)存在此屬性則返回
                          if (propertyValues.getPropertyValue(propertyName = descriptor.getName()) != null
                              
          continue;
                          
                          
          // 屬性?描述類中有寫方法(setter)并且指定方法上有注解標(biāo)記
                          if ((method = descriptor.getWriteMethod()) != null
                                  
          && (inject = AnnotationUtils.getAnnotation(method, Inject.class)) != null{
                              
          // 關(guān)聯(lián)Bean的名?稱
                              String targetBeanName = StringUtils.hasText(inject
                                      .value()) 
          ? inject.value() : propertyName;
                              
          // 建立關(guān)聯(lián)Bean的屬性類        
                              propertyValues.addPropertyValue(new PropertyValue(propertyName,
                                      
          new RuntimeBeanReference(targetBeanName)));
                          }

                      }

                  }

              }


              
          /**
               * 根據(jù)Bean定義信息名得到Bean Class
               * 
               * 
          @param name Bean定義信息名稱
               * 
          @param definition Bean定義信息
               * 
          @return Bean Class
               * 
          @throws BeansException
               
          */

              @SuppressWarnings(
          "unchecked")
              
          private Class getBeanClassByName(String name, BeanDefinition definition) 
                      
          throws BeansException {
                  
                  
          try {
                      
          return Class.forName(definition.getBeanClassName());
                  }
           catch (ClassNotFoundException e) {
                      
          throw new CannotLoadBeanClassException("No class found", name, 
                              definition.getBeanClassName(), e);
                  }

              }

          }

           

          public class DaoA implements IDaoA {

              
          private String param;
              
              
          public void operationA() {
                  System.out.println(
          "DaoA.operationA(" + param + ")");
              }


              
          public String getParam() {
                  
          return param;
              }


              
          public void setParam(String param) {
                  
          this.param = param;
              }

          }

          public class DaoB implements IDaoB {

              
          public void operationB() {
                  System.out.println(
          "DaoB.operationB()");
              }

          }

          public class Service implements IService {

              
          private IDaoA daoA = null;
              
              
          private IDaoB daoB = null;
              
              
          public void service() {
                  System.out.println(
          "********service begin ***********");
                  daoA.operationA();
                  daoB.operationB();
                  System.out.println(
          "********service end *************");
              }


              
          public IDaoA getDaoA() {
                  
          return daoA;
              }


              @Inject
              
          public void setDaoA(IDaoA daoA) {
                  
          this.daoA = daoA;
              }


              
          public IDaoB getDaoB() {
                  
          return daoB;
              }


              @Inject
              
          public void setDaoB(IDaoB daoB) {
                  
          this.daoB = daoB;
              }

          }
          (注意set方法)

          配置文件
          <?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="daoA" class="injection.DaoA">
                  
          <property name="param">
                      
          <value>lg</value>
                  
          </property>
              
          </bean>
              
              
          <bean id="daoB" class="injection.DaoB"/>
              
          <bean id="service" class="injection.Service"/>
              
              
          <bean id="injection" class="injection.InjectProcessor"/>
          </beans>
          ApplicationContext會檢測部署在它之上實現(xiàn)了BeanFactoryPostProcessor接口的bean,并在適當(dāng)?shù)臅r候會自動調(diào)用bean工廠后配置處理器。部署一個后配置處理器同部署其它bean沒什么區(qū)別。

          測試類
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.ClassPathXmlApplicationContext;

          public class AnnotationInjectTest {

              
          public static void main(String[] args) {
                  ApplicationContext ac 
          = new ClassPathXmlApplicationContext("injection/applicationContext.xml");
                  
                  IService service 
          = (IService) ac.getBean("service");
                  service.service();
              }

          }

          測試結(jié)果如下:
          ********service begin ***********
          DaoA.operationA(lg)
          DaoB.operationB()
          ********service end *************

          posted on 2008-12-17 01:17 永遠(yuǎn)的火焰舞者 閱讀(567) 評論(0)  編輯  收藏 所屬分類: spring


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(1)

          隨筆分類(10)

          隨筆檔案(9)

          文章檔案(1)

          搜索

          最新評論

          • 1.?re: JForum安裝
          • 我就是想研究下sso,哈哈!再在JForum的基礎(chǔ)上二次開發(fā)玩玩 呵呵
          • --Jlg
          • 2.?re: JForum安裝
          • JForum的代碼還比較清晰,但談不上強大,雖然一般也足夠用了。
          • --一農(nóng)

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 东乌| 乐山市| 获嘉县| 辰溪县| 马边| 泰安市| 日照市| 陇南市| 连南| 舒城县| 宣化县| 哈尔滨市| 汶上县| 江川县| 平乐县| 深水埗区| 舟山市| 鄂州市| 岳阳市| 延吉市| 博白县| 靖西县| 宁津县| 辽宁省| 浑源县| 彭阳县| 大关县| 德清县| 巴彦县| 丁青县| 江安县| 南涧| 泾源县| 上高县| 凤翔县| 无极县| 如皋市| 泰宁县| 濮阳县| 达州市| 赤水市|