Never give up!

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

           

          Inject Bean By Annotation

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

          代碼如下:
          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主要描述?一個(gè)屬性和此屬性的?一對(duì)訪問(wèn)方?法(getter and setter)
                       
          */

                      
          for (PropertyDescriptor descriptor : BeanUtils.getPropertyDescriptors(
                              getBeanClassByName(beanDefinitionName, beanDefinition))) 
          {
                          
          // 屬?性?集合中已經(jīng)存在此屬性則返回
                          if (propertyValues.getPropertyValue(propertyName = descriptor.getName()) != null
                              
          continue;
                          
                          
          // 屬性?描述類中有寫(xiě)方法(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會(huì)檢測(cè)部署在它之上實(shí)現(xiàn)了BeanFactoryPostProcessor接口的bean,并在適當(dāng)?shù)臅r(shí)候會(huì)自動(dòng)調(diào)用bean工廠后配置處理器。部署一個(gè)后配置處理器同部署其它bean沒(méi)什么區(qū)別。

          測(cè)試類
          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();
              }

          }

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

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


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


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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(1)

          隨筆分類(10)

          隨筆檔案(9)

          文章檔案(1)

          搜索

          最新評(píng)論

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

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 沾化县| 腾冲县| 克拉玛依市| 凌海市| 常宁市| 景洪市| 九寨沟县| 壤塘县| 甘南县| 陆良县| 彩票| 龙江县| 施秉县| 晋中市| 怀安县| 灌云县| 武陟县| 青岛市| 泰和县| 双峰县| 长垣县| 磐安县| 神木县| 岳池县| 田林县| 鄄城县| 甘南县| 景谷| 邮箱| 固原市| 枣庄市| 阳曲县| 奎屯市| 南部县| 临海市| 常德市| 白银市| 德庆县| 巴楚县| 淮南市| 上思县|