java - 使用依赖注入(inject)实现数据访问 API

标签 java web-services api dependency-injection guice

我是编写 API 的新手,做了一些研究并意识到要完成我想要的任务,我需要使用依赖注入(inject)来完成它。我正在编写一个有两个数据源的Android应用程序。一种是通过 Web 服务公开,另一种是 SQLlite。 SQLlite在没有数据连接时用作备份(暂时只对API的webservice部分感兴趣,会重构)。我想编写一个 API,提供一个抽象层,根据所需的模型调用正确的数据访问类。因此,我有一个描述 api 应该实现的方法的接口(interface),称为 IDataAccess(仅对 getAll 感兴趣,以便弄清楚要做什么)。

public interface IDataAccess {  
    public <T> List <T> getAll ();  
    public <T> T getById (int id);
}//end  IDataAccess

我正在使用 Guice 进行依赖注入(inject)。 guice模块是:

public class Data extends AbstractModule {
    public void configure () {
        bind (IDataAccess.class).to(UserData.class);
    }
}

IDataAccess 的实现是(注意我正在使用 Jersey Client API):

public class UserData extends DataAccessManager implements IDataAccess {    
    @SuppressWarnings("unchecked")
    public List <User> getAll () {
        WebResource webResource = client.resource (WebResourceURL.URL_USER_ALL);
        ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
        if (response.getStatus () == 200)
            return response.getEntity(new GenericType <List <User>> () {}) ;
        else
            return null;        
    }//end getAllUsers method
}

我有一个类可以加载并实例化所需的任何资源。它还返回一个名为 DataAccessFactory 的 DataManager 实例。

public class DataAccessFactory {
    private Client client;
    private static DataAccessFactory instance;
    private DataAccessFactory() {
        client = Client.create();
    }
    public static DataAccessFactory getInstance() {
        /*
         * check if instance  variable is instantiated.
         * if it is not then instantiated it and returns
         * created instance.
         */
        if (instance == null) {
            instance = new DataAccessFactory();
            return instance;
        } else
            return instance;
    }//end getInstance method
    public DataAccessManager createDataAccessManager() {
        return new DataAccessManager(client);
    }//end createDataAccessManager method
}

然后我就有了实际的 DataAccessManager 类:

public class DataAccessManager {
    protected Client client;
    protected DataAccessManager (Client client)n{
        this.client = client;
    }//end constructor 
    public <T>  List <Object> getAll(T t) {
        Data module = new Data ();
        Injector injector = Guice.createInjector(module);
        IDataAccess data = (IDataAccess) injector.getInstance(t.getClass());
        return (List<Object>) data;
    }//end fetchAllUser method
}

要调用此类上的用户模型,我会执行以下操作:

@Test
public void fetchUser () {
        DataAccessManager m = DataAccessFactory.getInstance().createDataAccessManager();
        List<User> user = (List<User>)  m.getAll(new Userdata ());
        if (user == null)
            assertEquals(1, 2);
        else
            assertEquals(1, 1);
}

理想情况下,我现在想要做的是,调用 UserData 来获取所有 User 对象或 OrderData(编写实现时)类来获取所有订单对象等。

问题是这给出了一个错误:

Cannot cast from List to List

.我怎样才能解决这个问题或重组这个问题以使其有意义?

最佳答案

1) 您正在为每个请求创建一个注入(inject)器 (Guice.createInjector)。注入(inject)器的创建非常昂贵,通常应该在应用程序加载期间完成。您应该将 DI 视为一种引导机制并保持简单。

2) 您不需要 DataAccessFactory。首先,不需要工厂,因为 createDataAccessManager 实例化不需要任何逻辑;其次,Guice 也可以处理工厂模式。

我个人会保持简单,并使用 Guice 直接将 UserData 实例注入(inject)到每个需要它的服务中,而不使用此处显示的相当复杂的抽象方法。尽管如此,它并没有解决处理网络问题的问题。我的猜测是,每个数据访问类都必须以特定的方式处理连接,因此逻辑应该直接在这里。

关于列表转换问题,请参见http://docs.oracle.com/javase/tutorial/java/generics/subtyping.html

如果您继续这样做,我建议您阅读 erasure还。

关于java - 使用依赖注入(inject)实现数据访问 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12957911/

相关文章:

java - 使用提供静态内容的辅助tomcat文件夹调试java web应用程序

java - SQL WHERE 无法与 Discord 一起使用

java - 处理 JDialog 和 JToggleButton 的状态和事件序列

java - 如何在Java中使用正则表达式提取HTML <td>标签数据?

web-services - 将数据保存在 Axis 对象中

javascript - 有没有好的 Web 前端绘制工具的开放 API?

ios - 如何快速从谷歌日历 API 获取 JSON?

eclipse - Mule 和 Eclipse 的 WSDL 问题

java - 每次调用webservice之前我们需要生成token id吗

ios - 这个功能对吗?调用带闭包的函数(swift - iOS)