【问题标题】:how to pass a datasource to a library?如何将数据源传递给库?
【发布时间】:2023-04-02 05:37:02
【问题描述】:

我正在编写一个从特定数据模式中检索数据的库。这个库包含一个可以是任何东西的 Datasource 对象。现在我已经在库中定义了我想避免的数据源的名称。

import javax.sql.DataSource

public class MyLibraryDao.java {
   private static final DS_NAME = "MY_DS_NAME";

   @Resource(name = "default", lookup = DS_NAME , type = DataSource.class)
   protected DataSource dataSource;
}

DAO 类不直接暴露给客户端。中间有一个服务层:

import javax.inject.Inject;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Model;

@ApplicationScoped
@Model
public class MyLibraryService {

    @Inject
    MyLibraryDao dao;
}

现在,如何将数据源对象传递给库?

我假设我需要在 DAO 中创建一个带有 DataSource 的构造函数,但是服务呢? 该库将在 CDI 环境中使用。

【问题讨论】:

  • 是的,它是 javax.sql.DataSource 不,我没有使用 Spring

标签: java cdi


【解决方案1】:

首先你的库需要一个数据源,让我们声明依赖:

public class MyLibraryDao {
   @Inject
   protected DataSource dataSource;
}

现在使用该库的应用程序的其余部分负责向 CDI 提供数据源;一个简单的方法是:

// Example; your implementation may vary
public class AppDatasourceProducer {
    private static final DS_NAME = "MY_APP_DS_NAME";

    @Resource(name = "default", lookup = DS_NAME , type = DataSource.class)
    protected DataSource dataSource;

    @Produces
    @ApplicationScoped
    public DataSource getDatasource() {
        return dataSource;
    }
}

发生了什么变化?现在您的应用程序负责了解数据源名称提供数据源本身。上面的示例可以在遵循 @Resource 注释的 JEE 环境中工作。为提供者使用不同的实现将适用于例如桌面环境(独立应用程序),使您的库可重用。

确切的数据源名称可能是固定的,就像在示例中一样,或者从配置中读取,例如来自系统属性(如评论中提到的);例如:

// Example 2, DS name from system properties
@ApplicationScoped
public class AppDatasourceProducer {
    protected DataSource dataSource;

    @PostConstruct
    void init() throws Exception {
        String dsName = System.getProperty("XXXXX");
        InitialContext ic = new InitialContext();
        dataSource = (DataSource) ic.lookup(dsName);
    }

    @Produces
    @ApplicationScoped
    public DataSource getDatasource() {
        return dataSource;
    }
}

更进一步:

  1. 无论出于何种原因,使用您的库的应用程序可能正在使用多个数据源。您可能需要提供一个限定符来指定您的应用要使用的数据源。
  2. 为了简单起见,我在MyLibraryDao 中使用了现场注入。如果您更改为构造函数注入,那么至少MyLibraryDao 也可以在非CDI 环境中使用,即如果您以某种方式获得了DataSource,您现在可以执行new MyLibraryDao(datasource)。可重用性更高。

【讨论】:

  • 谢谢,这似乎有效。如果我有另一个库也需要不同的数据源怎么办?
  • 我可以想到 2 个选项:1) 您可能希望生成的不是 DS,而是特定于库的数据源提供程序 - 具有 DataSource getDataSource() 方法的类。这些是每个库的不同类型,可以解决问题。 2) 您可以使用 CDI 限定符来区分相同 Java 类型但用途不同的 bean。所以每个库都为 DS 定义了自己的限定符(它只是一个注释)。
猜你喜欢
  • 1970-01-01
  • 2020-11-26
  • 2018-08-05
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多