J2EE之巔

           

          Spring2.5的組件自動(dòng)搜索

          http://dev2dev.bea.com.cn/blog/chaocai/200712/spring_osgi_04_719.html

          posted on 2007-12-04 12:50 超越巔峰 閱讀(2736) 評(píng)論(1)  編輯  收藏 所屬分類: Java EE

          評(píng)論

          # re: Spring2.5的組件自動(dòng)搜索 2007-12-04 19:24 BeanSoft

          姓名: 蔡超 生日: 1976-09-03 總結(jié): 六年大企業(yè)軟件開發(fā)經(jīng)驗(yàn)(其中兩年任軟件架構(gòu)師),精通J2EE相關(guān)技術(shù)及架構(gòu)設(shè)計(jì),是SUN及Microsoft培訓(xùn)中心特邀高端講師 SUN認(rèn)證的J2EE架構(gòu)師(SCEA) SUN認(rèn)證的商務(wù)組件開發(fā)員(SCBCD) IBM認(rèn)證的RUP專家 IBM認(rèn)證的OOA&D (UML v2)專家




          對(duì)于annotation的支持和組件的配置方式是擴(kuò)充是spring2.5的主要提升之一。其中組件在類路徑下的自動(dòng)搜索功能也是一項(xiàng)值得注意的新增特性。
          現(xiàn)來看個(gè)示例:

          圖表 1 示例中涉及的類的關(guān)系
          Command.java:
          package org.ccsoft.commands.imp;

          public interface Command {
          public void execute();
          }

          CommandExecuter.java:
          package org.ccsoft.commands.imp;

          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.stereotype.Component;
          @Component("commandExecuter")
          public class CommandExecuter {
          private Command command;
          @Autowired

          public void setCommand(/*@Qualifier("helloCommand")*/ Command command) {
          this.command = command;
          }
          public void executeCommand(){
          command.execute();
          }
          }

          HelloCommand.java
          package org.ccsoft.commands.imp;

          import org.springframework.stereotype.Component;


          @Component
          public class HelloCommand implements Command{
          public void execute() {
          System.out.println("Hello World");
          }
          }

          配置文件:
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"" target="_new">http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"" target="_new">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/context
          http://www.springframework.org/schema/context/spring-context-2.5.xsd">

          <context:component-scan base-package="org.ccsoft"/>
          </beans>

          測試程序如下:
          package org.ccsoft;

          import org.ccsoft.commands.imp.CommandExecuter;
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.ClassPathXmlApplicationContext;

          import junit.framework.TestCase;

          public class TestCommandExecuter extends TestCase {
          public void testExecuteCommand(){
          ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml");
          CommandExecuter exe=(CommandExecuter) ctx.getBean("commandExecuter");
          exe.executeCommand();
          }
          }
          可以從配置文件中發(fā)現(xiàn),這次并沒有像常規(guī)的方式那樣,聲明所使用的bean,只是說明了組件搜索的基路徑(便于減少搜索范圍)“<context:component-scan base-package="org.ccsoft"/>”。
          要點(diǎn):
          1 用@Component來聲明每個(gè)組件,而不是通過配置文件中的bean元素
          2 在需要注入其他組件的地方使用@Autowired,默認(rèn)情況下會(huì)按類型進(jìn)行依賴關(guān)系的查找和注入
          3 可以指定組件的Id,通過@Component的值,如:@Component("commandExecuter"),這樣類似于<bean id=” commandExecuter”…,注意如果不注明該值,spring將使用默認(rèn)的命名規(guī)則,即類的名字但首字母小寫,所以在上例中將@Component("commandExecuter")改寫為@Component同樣是可以運(yùn)行的。

          代碼試驗(yàn)二:
          在上面工程中加入新的Command接口實(shí)現(xiàn)類SorryCommand.
          package org.ccsoft.commands.imp;

          import org.springframework.stereotype.Component;
          @Component
          public class SorryCommand implements Command {

          public void execute() {
          // TODO Auto-generated method stub
          System.out.println("Sorry");
          }

          }
          再運(yùn)行測試程序,會(huì)發(fā)現(xiàn)程序無法運(yùn)行,拋出以下異常org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.ccsoft.commands.imp.Command] is defined: expected single matching bean but found 2: [helloCommand, sorryCommand]
          這是因?yàn)楦鶕?jù)類型的方式搜索,找到了兩個(gè)相符的依賴類,這是我們必須指明使用那個(gè)組件。
          @Autowired

          public void setCommand(@Qualifier("helloCommand") Command command) {
          this.command = command;
          }
          要點(diǎn):
          4 在多個(gè)同類組件存在于查找路徑時(shí)必須通過@Qualifier指明

          不知為什么,spring的這一新特性總讓我聯(lián)想起OSGi DS,不過與OSGi DS相比個(gè)人認(rèn)為spring的IoC還是有些不便的地方,OSGi DS的Service的引用策略中的Cardinality可以指定組件的注入策略,可以支持將多個(gè)符合條件的組件多次注入,這為編寫組件容器這樣的應(yīng)用提供了很大的便利。
          如:

          private List<Command> commands;

          public void setCommand(Command cmd){
          commands.add(cmd);
          }

          ….

          最后,這里只是涉及了spring2.5中相關(guān)內(nèi)容中非常少的一點(diǎn),如果大家有興趣深入了解可以參考spring reference。
          個(gè)人認(rèn)為在大家充分享受新特性帶來的便利的同時(shí)也要主要到新特性是否會(huì)對(duì)應(yīng)用的可維護(hù)性和部署時(shí)改變注入關(guān)系的方便性帶來負(fù)面影響。



          蔡超
          JavaEE 咨詢顧問
          SCEA
          IBM Certified Solution Designer for OOA&D UML2




          Tags: Spring OSGi

            回復(fù)  更多評(píng)論   

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(12)

          隨筆分類(54)

          隨筆檔案(59)

          文章分類(2)

          文章檔案(1)

          相冊

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 石城县| 介休市| 沙湾县| 普宁市| 望城县| 桐庐县| 海晏县| 永丰县| 巴南区| 常熟市| 屯昌县| 临夏县| 轮台县| 温州市| 清河县| 通海县| 常德市| 武穴市| 土默特左旗| 菏泽市| 长海县| 和顺县| 邛崃市| 逊克县| 碌曲县| 凤阳县| 大化| 镇平县| 太和县| 岳池县| 额尔古纳市| 剑河县| 杭锦后旗| 河源市| 太谷县| 遂川县| 韶山市| 师宗县| 新化县| 黄平县| 陆河县|