03.依賴注入(DI/IoC)

CDI and ManagedBean

這樣的設計模式在實質上, 它反映的是一種物件間的依賴關係 ....

控制反轉(英文縮寫為IoC),也叫做依賴注入(Dependency Injection)。 簡稱DI。
是物件導向程式中的一種設計原則,可以用來減低程式碼之間的耦合度。



控制反轉(IoC)及依賴注入(DI)


讓物件間的依賴關係能盡可能在受單方改變時, 能不變更其Code的情況下, 其關係能順利移轉.
  • 程序應不依賴實作, 而是依賴介面(Interface)
  • 實作必須依賴抽象, 而不是抽象依賴實作.

DI 型態

Type1 介面注入

缺點:反讓應用程序對容器產生依賴

Type2 設值注入

較佳的建議(@ManagedProperty)
依賴至 Interface

Type3 建構子注入

        創建一個帶參數的建構子




JSF & DI


JSF 為了達到 IoC 的目的, 依 IoC 要求 Container 或者 Framework 引入一個裝配器(Assembler)物件, JSF 使用 Managed Bean 來擔任這個 Role.






@ManagedProperty


既然@ManagedProperty註解是標準JSF注入的一種簡寫形式,那麼注入的發生時機與標準JSF的ManagedBean生命週期是一致的,也就是說,注入動作發生在ManagedBean創建之後(構造方法執行之後)。當ManagedBean中所有ManagedProperty注入完成後,容器將調用@PostConstruct註解的生命週期回調方法。可以看出,@ManagedProperty註解所定義的注入 是與ManagedBean自身的生命週期相關的。

@ManageProperty(value="...")

Before CDI
@ManagedBean(name = "customer")
@SessionScoped
public class CustomerController {
    private CustomerJpaController jpaController;

    public CustomerController() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        jpaController = (CustomerJpaController)facesContext.getApplication()
                        .getELResolver().getValue(facesContext.getELContext(), null, "customerJpa");
    }   
    
}

@ManagedBean(name="customerJpa")
@SessionScoped
public class CustomerJpaController {
    // customerJpa content
}

After CDI
@ManagedBean(name = "customer")
@SessionScoped
public class CustomerController {

    @ManagedProperty(value = "#{customerJpa}")
    private CustomerJpaController jpaController;

    public CustomerController() {
        
    }

    public void setJpaController(CustomerJpaController jpaController) {
          this.jpaController = jpaController;
      }   
    
}

@ManagedBean(name="customerJpa")
@SessionScoped
public class CustomerJpaController {
    // customerJpa content
}

CDI using Implicit Object
@ManagedProperty(value="#{sessionScope}")
private Map<String, Object> sessionMap;

API Doc, http://java.sun.com/javaee/6/docs/api/javax/faces/bean/ManagedProperty.html

http://infocenter.apusic.com/help/index.jsp?topic=/operamasks-sdk/v2.3/ch12s07.html (失連)

http://mkblog.exadel.com/jsf/learning-jsf2-managed-beans/

@Inject


都是注入完成功能,@Inject 和@ManagedProperty 有什麼區別呢,
  • @Inject 是在需要調用這個類的時候才進行初始化
  • @ManagedProperty是一旦調用者被初始化,則被調用者跟著被實例化,
兩者的時機稍有不同



Tutorial


http://www.operamasks.org/article/static/ART00033.html






References


  1. Martin Fowler, Inversion of Control Containers and the Dependency Injection pattern,
    1. http://martinfowler.com/articles/injection.html
  2. http://en.wikipedia.org/wiki/Inversion_of_control
  3. http://zh.wikipedia.org /zh-tw/控制反轉
Subpages (1): IoC(控制反轉技術)
Comments