我可以自动连接适配器 Class 吗?
Can I Autowire an Adapter Class?
我创建了一个单例 class,它用作我们的 Influx 数据库的适配器。它基本上看起来像:
public class InfluxDBAdapter {
// some private static final query Strings
private static InfluxDBAdapter adapter = null;
private static InfluxDB influxDB;
private InfluxDBAdapter() {}
public static InfluxDBAdapter getInstance() {
if (adapter == null) {
adapter = new InfluxDBAdapter();
influxDB = InfluxDBFactory.connect(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
}
return adapter;
}
// some more methods to utilize the database
}
然后在另一个 class 中,我这样使用它:
@Service
public class SomeService {
private InfluxDBAdapter adapter;
public SomeService() {}
@PostConstruct
public void init() {
adapter = InfluxDBAdapter.getInstance();
}
}
所以这行得通,但我正在重构我的代码,我想知道是否可以简单地自动装配我的 InfluxDBAdapter class 与我目前正在做的事情相比,仍然可以实现结果相同?
是的,这应该有效。 Spring 可以调用私有构造函数,所以应该没有任何问题。
但是你为什么要这样做呢?单例模式违背了依赖注入的基本原则。如果您想要一个单例 InfluxDBAdapter
bean,只需将其设为单例 bean。
我建议添加一个配置 class,它看起来像
@Configuration
public class InfluxDBConfig {
// constants omitted...
@Bean
public InfluxDB influxDB() {
final InfluxDB influxDB = InfluxDB(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
return influxDB;
}
}
然后您可以用 @Component
注释 InfluxDBAdapter
因为可以注入 InfluxDB
实例。当然,相应地修改 InfluxDB
和 InfluxDBAdapter
classes 的构造函数。
其中一些常量可能可以通过配置属性提供,这样您的配置逻辑就不会与您的业务逻辑混淆。
创建一个 @Configuration
class 来构造 InfluxDB
以及您的适配器。有了这个,您甚至可以使用 Spring 引导属性支持。
@Configuration
public class InfluxDBConfiguration {
@Bean
public InfluxDB influxDB() {
InfluxDB influxDB = InfluxDBFactory.connect(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
return influxDB;
}
@Bean
public InfluxDBAdapter influxDBAdapter(InfluxDB influxDB) {
return new InfluxDBAdapter(influxDB);
}
}
现在您的 InfluxDBAdapter
需要一个构造函数(用于依赖注入)来检索 InfluxDB
。
public class InfluxDBAdapter {
// some private static final query Strings
private InfluxDB influxDB;
InfluxDBAdapter(InfluxDB influxDB) {
this.influxDB=influxDB;
}
// some more methods to utilize the database
}
确保 InfluXDBConfiguration
和 InfluxDBAdapter
在同一个包中,以便可以调用默认可见构造函数(默认可见以防止,简单,外部实例化)。
在 InflxuDBConfiguration
中,您可以删除包含硬编码用户名等的 static
字段,并将其替换为访问 Environment
或使用带注释的 @ConfigurationProperties
class 与 type safe properties 一起工作。
@ConfigurationProperties(prefix="influxdb")
@Component
public class InfluxDBProperties {
private String url = "default-url";
private String dbName = "default-dbname";
private String username = "default-user";
private String password = "default-pwd";
// Other properties of your liking;
// getters & setters
}
现在有了这个 InfluxDBProperties
,您可以将 influx.url=http://whatever
添加到您的 application.properties
或个人资料特定的 externally configurable。您可以将其注入 influxDB
方法以从中检索属性。
@Bean
public InfluxDB influxDB(InfluxDBProperties props) {
InfluxDB influxDB = InfluxDBFactory.connect(props.getUrl(), props.getUsername(), props.getPassword());
influxDB.query(new Query(CREATE_DB, props.getDbName()));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(props.getDbName());
return influxDB;
}
不再需要静态变量,可针对每个环境进行配置。
我创建了一个单例 class,它用作我们的 Influx 数据库的适配器。它基本上看起来像:
public class InfluxDBAdapter {
// some private static final query Strings
private static InfluxDBAdapter adapter = null;
private static InfluxDB influxDB;
private InfluxDBAdapter() {}
public static InfluxDBAdapter getInstance() {
if (adapter == null) {
adapter = new InfluxDBAdapter();
influxDB = InfluxDBFactory.connect(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
}
return adapter;
}
// some more methods to utilize the database
}
然后在另一个 class 中,我这样使用它:
@Service
public class SomeService {
private InfluxDBAdapter adapter;
public SomeService() {}
@PostConstruct
public void init() {
adapter = InfluxDBAdapter.getInstance();
}
}
所以这行得通,但我正在重构我的代码,我想知道是否可以简单地自动装配我的 InfluxDBAdapter class 与我目前正在做的事情相比,仍然可以实现结果相同?
是的,这应该有效。 Spring 可以调用私有构造函数,所以应该没有任何问题。
但是你为什么要这样做呢?单例模式违背了依赖注入的基本原则。如果您想要一个单例 InfluxDBAdapter
bean,只需将其设为单例 bean。
我建议添加一个配置 class,它看起来像
@Configuration
public class InfluxDBConfig {
// constants omitted...
@Bean
public InfluxDB influxDB() {
final InfluxDB influxDB = InfluxDB(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
return influxDB;
}
}
然后您可以用 @Component
注释 InfluxDBAdapter
因为可以注入 InfluxDB
实例。当然,相应地修改 InfluxDB
和 InfluxDBAdapter
classes 的构造函数。
其中一些常量可能可以通过配置属性提供,这样您的配置逻辑就不会与您的业务逻辑混淆。
创建一个 @Configuration
class 来构造 InfluxDB
以及您的适配器。有了这个,您甚至可以使用 Spring 引导属性支持。
@Configuration
public class InfluxDBConfiguration {
@Bean
public InfluxDB influxDB() {
InfluxDB influxDB = InfluxDBFactory.connect(URL, USERNAME, PWD);
influxDB.query(new Query(CREATE_DB, DB_NAME));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(DB_NAME);
return influxDB;
}
@Bean
public InfluxDBAdapter influxDBAdapter(InfluxDB influxDB) {
return new InfluxDBAdapter(influxDB);
}
}
现在您的 InfluxDBAdapter
需要一个构造函数(用于依赖注入)来检索 InfluxDB
。
public class InfluxDBAdapter {
// some private static final query Strings
private InfluxDB influxDB;
InfluxDBAdapter(InfluxDB influxDB) {
this.influxDB=influxDB;
}
// some more methods to utilize the database
}
确保 InfluXDBConfiguration
和 InfluxDBAdapter
在同一个包中,以便可以调用默认可见构造函数(默认可见以防止,简单,外部实例化)。
在 InflxuDBConfiguration
中,您可以删除包含硬编码用户名等的 static
字段,并将其替换为访问 Environment
或使用带注释的 @ConfigurationProperties
class 与 type safe properties 一起工作。
@ConfigurationProperties(prefix="influxdb")
@Component
public class InfluxDBProperties {
private String url = "default-url";
private String dbName = "default-dbname";
private String username = "default-user";
private String password = "default-pwd";
// Other properties of your liking;
// getters & setters
}
现在有了这个 InfluxDBProperties
,您可以将 influx.url=http://whatever
添加到您的 application.properties
或个人资料特定的 externally configurable。您可以将其注入 influxDB
方法以从中检索属性。
@Bean
public InfluxDB influxDB(InfluxDBProperties props) {
InfluxDB influxDB = InfluxDBFactory.connect(props.getUrl(), props.getUsername(), props.getPassword());
influxDB.query(new Query(CREATE_DB, props.getDbName()));
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
influxDB.setDatabase(props.getDbName());
return influxDB;
}
不再需要静态变量,可针对每个环境进行配置。