分离å…Ïx³¨åQ?Separation of Concerns : SOCåQ‰æ˜¯Ioc模å¼å’ŒAOP产生最原始动力åQŒé€šè¿‡åŠŸèƒ½åˆ†è§£å¯å¾—到关注点åQŒè¿™äº›å…³æ³¨å¯ä»¥æ˜¯ ¾l„äšgComponents, æ–šw¢Aspects或æœåŠ¡Servicesã€?/p>
  从GoF设计模å¼ä¸ï¼Œæˆ‘们已ç»ä¹ 惯一¿Uæ€ç»´¾~–程方å¼åQšInterface Driven Design 接å£é©±åЍåQŒæŽ¥å£é©±åŠ¨æœ‰å¾ˆå¤šå¥½å¤„åQŒå¯ä»¥æä¾›ä¸åŒçµ‹zÈš„å类实现åQŒå¢žåР代ç 稳定和å¥å£®æ€§ç‰½{‰ï¼Œä½†æ˜¯æŽ¥å£ä¸€å®šæ˜¯éœ€è¦å®žçŽ°çš„åQŒä¹Ÿž®±æ˜¯å¦‚下è¯å¥˜qŸæ—©è¦æ‰§è¡Œï¼š
  AInterface a = new AInterfaceImp();
  AInterfaceImp是接å£AInterface的一个å¾c»ï¼ŒIoc模å¼å¯ä»¥å»¶ç¼“接å£çš„实玎ͼŒæ ÒŽ(gu¨©)®éœ€è¦å®žçŽŽÍ¼Œæœ‰ä¸ªæ¯”å–»åQšæŽ¥å£å¦‚åŒç©ºçš„æ¨¡åž‹å¥—åQŒåœ¨å¿…è¦æ—Óž¼Œéœ€è¦å‘模型套注ž®„石è†ï¼Œ˜q™æ ·æ‰èƒ½æˆäØ“ä¸€ä¸ªæ¨¡åž‹å®žä½“ï¼Œå› æ¤åQŒæˆ‘们将äºÞZؓ控制接å£çš„实现æˆä¸?注射"ã€?/p>
  Ioc英文ä¸?Inversion of ControlåQŒå³åè{模å¼åQŒè¿™é‡Œæœ‰è‘—å的好莱åžç†è®ºåQšä½ 呆ç€åˆ«åЍåQŒåˆ°æ—¶æˆ‘ä¼šæ‰¾ä½ ã€?/p>
  其实Ioc模å¼ä¹Ÿæ˜¯è§£å†³è°ƒç”¨è€…和被调用者之间的一¿Uå…³¾p»ï¼Œä¸Šè¿°AInterface实现è¯å¥è¡¨æ˜Žå½“剿˜¯åœ¨è°ƒç”¨è¢«è°ƒç”¨è€…AInterfaceImpåQŒç”±äºŽè¢«è°ƒç”¨è€…å¿U°å†™å…¥äº†è°ƒç”¨è€…的代ç ä¸ï¼Œ˜q™äñ”生了一个接å£å®žçŽ°çš„åŽŸç½ªåQšå½¼æ¤è”¾p»ï¼Œè°ƒç”¨è€…和被调用者有紧密è”ç³»åQŒåœ¨UML䏿˜¯ç”¨ä¾èµ?Dependency 表示ã€?/p>
  但是˜q™ç§ä¾èµ–在分¼›Õd…³æ³¨çš„æ€ç»´ä¸‹æ˜¯ä¸å¯å¿è€çš„åQŒå¿…™åÕdˆ‡å‰ÔŒ¼Œå®žçŽ°è°ƒç”¨è€…å’Œè¢«è°ƒç”¨è€…è§£è€¦ï¼Œæ–°çš„Iocæ¨¡å¼ Dependency Injection 模å¼ç”±æ¤äº§ç”Ÿäº†ï¼Œ Dependency Injectionæ¨¡å¼æ˜¯ä¾èµ–注ž®„çš„æ„æ€ï¼Œä¹Ÿå°±æ˜¯å°†ä¾èµ–先剥¼›»ï¼Œç„¶åŽåœ¨é€‚å½“æ—¶å€™å†æ³¨å°„˜q›å…¥ã€?/p>
Ioc模å¼åQˆDependency Injection模å¼åQ‰æœ‰ä¸‰ç§åQ?/p>
½W¬ä¸€¿Uç±»åž?从JNDI或ServiceManager½{‰èŽ·å¾—è¢«è°ƒç”¨è€…ï¼Œ˜q™é‡Œ¾cÖM¼¼ServiceLocator模å¼ã€?1. EJB/J2EE
2. AvalonåQˆApacheçš„ä¸€ä¸ªå¤æ‚ä‹É用ä¸å¤šçš„™å¹ç›®åQ?
½W¬äºŒ¿Uç±»åž?使用JavaBeansçš„setteræ–ÒŽ(gu¨©)³• 1. Spring Framework,
2. WebWork/XWork
½W¬ä¸‰¿Uç±»åž?åœ¨æž„é€ æ–¹æ³•ä¸å®žçްä¾èµ– 1. PicoContainer,
2. HiveMind
  有过EJBå¼€å‘ç»éªŒçš„人都知é“åQŒæ¯ä¸ªEJB的调用都需è¦é€šè¿‡JNDIå¯ÀL‰¾åˆ°å·¥åŽ‚æ€§è´¨çš„Home接å£åQŒåœ¨æˆ‘的教程EJBæ˜¯ä»€ä¹ˆç« èŠ‚ä¸åQŒæˆ‘也是从ä¾èµ–和工厂模å¼è§’度æ¥é˜˜q°EJBçš„ä‹É用ã€?/p>
ã€€ã€€åœ¨é€šå¸¸ä¼ ç»Ÿæƒ…å†µä¸‹ï¼Œä¸ÞZº†å®žçŽ°è°ƒç”¨è€…å’Œè¢«è°ƒç”¨è€…è§£è€¦ï¼Œåˆ†ç¦»åQŒä¸€èˆ¬æ˜¯é€šè¿‡å·¥åŽ‚æ¨¡å¼å®žçŽ°çš„ï¼Œä¸‹é¢ž®†é€šè¿‡æ¯”较工厂模å¼å’ŒIoc模å¼ä¸åŒåQŒåŠ æ·Þq†è§£Ioc模å¼ã€?/p>
工厂模å¼å’ŒIoc
  å‡è®¾æœ‰ä¸¤ä¸ªç±»B å’?CåQšBä½œäØ“è°ƒç”¨è€…ï¼ŒC是被调用者,在B代ç ä¸å˜åœ¨å¯¹C的调用:
public class B{
   private C comp;
  ......
}
Â
  实现comp实例有两¿U途径åQšå•æ€å·¥åŽ‚æ¨¡å¼å’ŒIocã€?/p>
工厂模å¼å®žçް如䏋åQ?/p>
public class B{
   private C comp;
  private final static MyFactory myFactory = MyFactory.getInstance();
  public B(){
    this.comp = myFactory.createInstanceOfC();
  }
   public void someMethod(){
    this.comp.sayHello();
  }
  ......
}
Â
特点åQ?/p>
æ¯æ¬¡˜q行æ—Óž¼ŒMyFactory坿 ¹æ®é…¾|®æ–‡ä»¶XMLä¸å®šä¹‰çš„Cå类实现åQŒé€šè¿‡createInstanceOfC()生æˆC的具体实例ã€?
使用Iocä¾èµ–性注ž®? Dependency Injection )实现Picocontainer如下åQŒB¾cÕd¦‚åŒé€šå¸¸POJO¾c»ï¼Œå¦‚下åQ?/p>
public class B{
   private C comp;
  public B(C comp){
    this.comp = comp;
   }
   public void someMethod(){
    this.comp.sayHello();
   }
  ......
}
Â
å‡è®¾C接å£/¾cÀLœ‰æœ‰ä¸€ä¸ªå…·ä½“实现CImp¾c…R€‚当客户端调用Bæ—Óž¼Œä½¿ç”¨ä¸‹åˆ—代ç åQ?/p>
public class client{
   public static void main( String[] args ) {
    DefaultPicoContainer container = new DefaultPicoContainer();
    container.registerComponentImplementation(CImp.class);
    container.registerComponentImplementation(B.class);
    B b = (B) container.getComponentInstance(B.class);
    b.someMethod();
   }
}
Â
ã€€ã€€å› æ¤åQŒå½“客户端调用Bæ—Óž¼Œåˆ†åˆ«ä½¿ç”¨å·¥åŽ‚æ¨¡å¼å’ŒIoc有ä¸åŒçš„特点和区别:
  主è¦åŒºåˆ«ä½“现在B¾cÈš„代ç åQŒå¦‚æžœä‹É用IocåQŒåœ¨B¾cÖM»£ç 丞®†ä¸éœ€è¦åµŒå…¥ä“Q何工厂模å¼ç‰çš„代ç ï¼Œå› äØ“˜q™äº›å·¥åŽ‚æ¨¡å¼å…¶å®ž˜q˜æ˜¯ä¸ŽC有些间接的蔾p»ï¼Œ˜q™æ ·åQŒä‹É用Iocå½Õdº•解耦了Bå’ŒC之间的蔾p…R€?/p>
  使用Ioc带æ¥çš„代ä»äh˜¯åQšéœ€è¦åœ¨å®¢æˆ·ç«¯æˆ–其它æŸå¤„˜q›è¡ŒBå’ŒC之间è”系的组装ã€?/p>
  所以,Iocòq¶æ²¡æœ‰æ¶ˆé™¤Bå’ŒC之间˜q™æ ·çš„蔾p»ï¼Œåªæ˜¯è½¬ç§»äº†è¿™¿U蔾p…R€?br />  ˜q™ç§è”系转移实际也是一¿U分¼›Õd…³æ³¨ï¼Œå®ƒçš„å½±å“巨大åQŒå®ƒæä¾›äº†AOP实现的å¯èƒ½ã€?/p>
Iocå’ŒAOP
  AOP我们已ç»çŸ¥é“是一¿Ué¢å‘切é¢çš„¾~–程方å¼åQŒç”±äºŽIoc解放自由了B¾c»ï¼Œè€Œä¸”å¯ä»¥å‘B(t¨¤i)¾cÕd®žçŽ°æ³¨ž®„C¾cÕd…·ä½“实玎ͼŒå¦‚果把B¾cÀLƒ³åƒæˆ˜q行时的横å‘动作åQŒæ— 疑注入C¾cÕd¾cÕd°±æ˜¯AOPä¸çš„一¿UAdvice
  通过下列代ç 说明如何使用Picocontainer实现AOPåQŒè¯¥ä¾‹ç¨‹ä¸»è¦å®žçŽ°æ˜¯è®°å½•logger功能åQŒé€šè¿‡Picocontainerå¯ä»¥ä½¿ç”¨½Ž€å•一行,使所有的应用¾cÈš„记录功能‹È€‹z…R€?/p>
首先¾~–制一个记录接å£ï¼š
public interface Logging {
  public void enableLogging(Log log);
}
Â
有一个LogSwitcher¾c»ï¼Œä¸»è¦ç”¨æ¥‹È€‹zÕd…·ä½“应用ä¸çš„记录功能:
import org.apache.commons.logging.Log;
public class LogSwitcher
{
  protected Log m_log;
  public void enableLogging(Log log) {
    m_log = log;
    m_log.info("Logging Enabled");
  }
}
一般的普通应用JavaBeans都å¯ä»¥ç‘ô承这个类åQŒå‡è®¾PicoUserManager是一个用æˆïL®¡ç†ç±»åQŒä»£ç 如下:
public class PicoUserManager extends LogSwitcher
{
  ..... //用户½Ž¡ç†åŠŸèƒ½
}
public class PicoXXXX1Manager extends LogSwitcher
{
  ..... //业务功能
}
public class PicoXXXX2Manager extends LogSwitcher
{
  ..... //业务功能
}
Â
注æ„LogSwitcherä¸Log实例是由外界赋予的,也就是说å›_°†è¢«å¤–界注ž®„进入,下é¢çœ‹çœ‹ä½¿ç”¨Picocontainer是如何注ž®„Log的具体实例的ã€?/p>
DefaultPicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(PicoUserManager.class);
container.registerComponentImplementation(PicoXXXX1Manager.class);
container.registerComponentImplementation(PicoXXXX2Manager.class);
.....
Logging logging = (Logging) container.getComponentMulticaster();
logging.enableLogging(new SimpleLog("pico"));//‹È€‹z»log
Â
  ç”׃¸Šä»£ç å¯è§åQŒé€šè¿‡ä½¿ç”¨½Ž€å•一行logging.enableLogging()æ–ÒŽ(gu¨©)³•使所有的应用¾cÈš„记录功能‹È€‹z…R€‚è¿™æ˜¯ä¸æ˜¯ç±»ä¼¼AOPçš„advice实现åQ?/p>
  æ€ÖM¹‹åQŒä‹É用Ioc模å¼åQŒå¯ä»¥ä¸½Ž¡å°†æ¥å…·ä½“实玎ͼŒå®Œå…¨åœ¨ä¸€ä¸ªæŠ½è±¡å±‚‹Æ¡è¿›è¡Œæ˜q°å’ŒæŠ€æœ¯æž¶æž„ï¼Œå› æ¤åQŒIoc模å¼å¯ä»¥ä¸ºå®¹å™¨ã€æ¡†æž¶ä¹‹¾cÈš„软äšg实现æä¾›äº†å…·ä½“的实现手段åQŒå±žäºŽæž¶æž„技术ä¸ä¸€¿Ué‡è¦çš„æ¨¡å¼åº”用ã€?/p>