2014-09-19 64 views
1

我有一個GenericCrudController<E>,它封裝了我的GenericCrudBO<E>的一個實例,我的GenericCrudBO<E>封裝了我的GenericCrudDAO<E>的一個實例。所以,我想要做的是,例如,我的GenericCrudController<User>默認具有GenericCrudBO<User>的實現,當然,如果有的話。如果沒有,我想堅持通用的實現。我在項目中使用CDI,我認爲這是要走的路,但我不知道使用什麼註釋。上述的結構和場景隨之而來的:決定在@Inject中使用什麼實現

public abstract class GenericController<T extends BaseEntity> implements Serializable { 
    private static final long serialVersionUID = 1L; 

    protected List<T> list; 
    protected T entity; 
    protected T filter; 

    @Inject 
    @Named("crudBO") 
    protected CrudBO<T> bo; 

    /*IRRELEVANT CODE GOES THERE */ 
} 

@Named("crudBO") 
public class GenericCrudBO<E extends BaseEntity> implements CrudBO<E>{ 
    private static final long serialVersionUID = 1L; 

    @Inject 
    @Named("crudDAO") 
    protected GenericCrudDAO<E> dao; 

    @Override 
    @SuppressWarnings("unchecked") 
    public List<E> search(E filter) { 
     Class<E> clazz = (Class<E>) filter.getClass(); 
     return dao.search(clazz, filter); 
    } 

    /*IRRELEVANT CODE GOES THERE*/ 
} 

@Named("crudDAO") 
public class GenericCrudDAO<E extends BaseEntity> implements CrudDAO<E>{/*IRRELEVANT CODE GOES THERE*/} 

這些都是實現通用結構的一些例子:

public class UserBO extends GenericCrudBO<User>{ 
    /*IRRELEVANT CODE GOES THERE*/ 
    @Override 
    public List<User> search(User filter) { 
     /*SPEFIFIC CODE*/ 
    } 
} 

@Named(value="userController") 
@ViewScoped 
public class UserController extends GenericController<User>{ 

    @Inject private UserBO userBO; 

    @Override 
    public void search() { 
     if(filter != null) { 
      list = userBO.search(filter); 
     } else throw new RuntimeException(); 
    } 
} 

現在發現,我必須手動注入UserBO的實例,並覆蓋搜索方法能夠實現我調用UserBO的搜索方法而不是GenericCrudBO的目標。我所要求的是,如果它可能用一些CDI註解來實現,迫使處理器根據控制器的通用類型注入正確實現的實例。謝謝

+1

我只通過手動實現嵌套類型的具體實例來完成此操作。由於java泛型的本質,我想沒有更好的方法。但我很樂意被證明是錯誤的。 – 2014-09-20 09:35:36

+1

如果你提供了一個具體的例子,它會有所幫助。什麼是完全失敗? – 2014-09-20 19:55:51

+0

剛剛添加了一些具體的例子,希望它有助於:) @JohnAment – 2014-09-22 18:05:33

回答

0

我使用javax.enterprise.inject.Instance對象封裝了我的bo和dao,解決了這個問題。通過這種方式:

@Inject 
private Instance<CrudBO<T>> bo; 

public CrudBO<T> getBo() { 
    return bo.get(); 
} 

只是爲了把事情說清楚,CrudBO是GenericCrudBO實現了接口,所以, 知道,默認情況下GenericCrudBO標註有@default,我詮釋了專門的教學班,@Alternative:

@Alternative 
public class SpecializedCrudBO extends GenericCrudBO<SpecificClass>{ 
} 

我也宣告了替代BO的和DAO在beans.xml中:

<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 

    <alternatives> 
     <class>br.com.logtec.business.SpecializedCrudBO</class> 
     ... 
    </alternatives> 

</beans> 

現在CDI可以處理我的通用的Java bean在運行時,這也非常好,因爲我不需要創建大量的樣板類。

相關問題