簡體   English   中英

GWT請求工廠-如何使定位器工作

[英]GWT request factory - how to get locator working

我有一個工作的“請求工廠”示例,我想對其進行重構,以便可以將“ persist()”和“ remove()”之類的通用方法從域對象移到通用定位器中。 目前我有以下(工作)代碼:

泛型超類,其中包含所有域對象的ID和版本:

@MappedSuperclass  
public class EntityBase {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    // setter & getter

}

域對象。 它具有persist()和remove()方法,我想在類之外進行重構:

@Entity
@Table(name = "article")
public class Article extends EntityBase{

    public static Article findArticle(Long id) {
        //find article
    }


    public void persist() {
        // persist
    }

    public void remove() {
        // remove
    }

}

域對象的代理對象:

@ProxyFor(value = Article.class)
public interface ArticleProxy extends EntityProxy {

    // some getter and setters

}

我的域對象的請求對象:

@Service(value = Article.class)
public interface ArticleRequest extends RequestContext {

    Request<ArticleProxy> findArticle(Long id);

    InstanceRequest<ArticleProxy, Void> persist();

    InstanceRequest<ArticleProxy, Void> remove();
}

我的要求工廠:

public interface MyRequestFactory extends RequestFactory {

  ArticleRequest articleRequest();

}

---------------------------------------

現在,我的重構代碼不再起作用了:

我從域對象中刪除了persist()和remove()方法:

@Entity
@Table(name = "article")
public class Article extends EntityBase{

    public static Article findArticle(Long id) {
        //find article
    }

}

我這樣創建了定位器,並在此處添加了方法“ remove()”和“ persist()”(以及其他默認方法):

public class EntityLocator extends Locator<EntityBase, Long> {

    @Override
    public EntityBase create(Class<? extends EntityBase> clazz) {
        try {  
            return clazz.newInstance();  
        } catch (InstantiationException e) {  
            throw new RuntimeException(e);  
        } catch (IllegalAccessException e) {  
            throw new RuntimeException(e);  
        }  
    }

    @Override
    public EntityBase find(Class<? extends EntityBase> clazz, Long id) {
        return null;
    }


    @Override
    public Class<EntityBase> getDomainType() {
        return null;
    }

    @Override
    public Long getId(EntityBase domainObject) {
        return null;
    }

    @Override
    public Class<Long> getIdType() {
        return null;
    }

    @Override
    public Object getVersion(EntityBase domainObject) {
        return null;
    }

    public void persist(EntityBase domainObject){
        // persist something
    }

    public void remove(EntityBase domainObject){
        // remove
    }

}

我的代理對象鏈接到定位器(locator = EntityLocator.class):

@ProxyFor(value = Article.class, locator=EntityLocator.class)
public interface ArticleProxy extends EntityProxy {

    // getter and setters here

}

我的新Request對象看起來像這樣。 我將“ InstanceRequests”設置為“ Requests”,並根據定位器中的新方法更改了返回類型和參數:

@Service(value = Article.class)
public interface ArticleRequest extends RequestContext {

    Request<ArticleProxy> findArticle(Long id);

    Request<Void> persist(ArticleProxy article);

    Request<Void> remove(ArticleProxy article);

}

但是,現在對於persist()和remove()方法,出現錯誤“找不到類似於java.lang.Voidpersist()的域方法”的錯誤。 為什么在EntityLocator中查找無效? 我需要一個ServiceLocator嗎? 我不完全了解Google教程,因此鏈接示例不再可用。

我和你有同樣的問題。 GWTProject.org上的指南( http://www.gwtproject.org/doc/latest/DevGuideRequestFactory.html )不太清楚如何正確地實現這一點,盡管它是在兩行之間編寫的。

以下教程向我明確了該解決方案: http : //cleancodematters.com/2011/06/04/tutorial-gwt-request-factory-part-i/

對我而言,使用DAO一詞會混淆事物。 我不會使用DAO模式。 這就是我的透明持久層的用途。 但是,使用Locator需要一個額外的類,以將persist,remove和findX方法放入其中。它們將其稱為數據訪問對象(實際上是數據訪問對象),我更喜歡將其稱為Manager。

TL;博士

您嘗試放入Locator中的方法不要去那里。 您需要一個額外的類(稱為DAO或Manager)。

在您的RequestContext中將DAO / Manager用作服務

我認為您不能在定位器中放置persistremove方法。 該文檔並不建議您可以向定位器界面添加任意方法並從客戶端引用它們。 如果只想避免在每個實體類中復制persistremove方法,則可以將它們放在EntityBase類中。 我已經做到了,並且效果很好。

如果還希望避免在每個請求接口中重復這些功能,則可以使通用基類Request如下所示:

@SkipInterfaceValidation
public interface BaseEntityRequest<P extends EntityProxy> extends RequestContext {
    InstanceRequest<P, Void> persist();
    InstanceRequest<P, Void> remove();
}

並像這樣使用它:

public interface ArticleRequest extends BaseEntityRequest<ArticleRequest> {
    ...
}

盡管persist()remove()在定位器中是有道理的,但由於該實體完全不了解持久層,因此當前的RF api不支持此功能。 因此,您必須處理將這些方法添加到BaseEntity並找出在定位器中調用persist方法的方法。

我認為您可以打開一個需要此功能的gwt問題。

避免實體中使用某些方法的另一種方法是使用ValueProxy不是EntityProxy ,但是在這種情況下,您必須提供從客戶端保存/刪除這些對象的方法。

您的界面ArticleRequest配置不正確。 您需要像這樣糾正它。

@Service(value = SentenceServiceImpl.class, locator = SpringServiceLocator.class)
public interface SentenceServiceRequest extends RequestContext {

    Request<List<SentenceProxy>> getSentences();

    Request<Void> saveOrUpdate(SentenceProxy sentence);

}

定位:

public class SpringServiceLocator implements ServiceLocator {

    public Object getInstance(Class<?> clazz) {
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(RequestFactoryServlet.getThreadLocalServletContext());
        return context.getBean(clazz);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM