注入配置依赖
Injecting configuration dependency
我正在使用 spring 框架创建缓存客户端包装器。这是为我们的应用程序提供缓存层。现在,我们正在使用redis。我发现 spring-data-redis 库非常适合创建我的包装器。
我的应用程序会将配置 POJO 传递给我的包装器,然后使用我将提供的接口。
spring-data-redis 提供了一种使用两个变量访问 redis 的简单方法。
RedisConnectionFactory
RedisTemplate<String, Object>
尽管如此,我会为我的应用程序提供更好的界面,我的界面函数如下:
public Object getValue( final String key ) throws ConfigInvalidException;
public void setValue( final String key, final Object value ) throws ConfigInvalidException;
public void setValueWithExpiry(final String key, final Object value, final int seconds, final TimeUnit timeUnit) throws ConfigInvalidException;
我仍然想提供 RedisConnectionFactory 和 RedisTemplate bean。
我的问题是如何使用此配置 POJO 初始化我的包装器应用程序?
目前我的配置是这样的:
import java.util.List;
public class ClusterConfigurationProperties {
List<String> nodes;
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
我的 AppConfig.java 看起来像这样:
import com.ajio.Exception.ConfigInvalidException;
import com.ajio.configuration.ClusterConfigurationProperties;
import com.ajio.validator.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class AppConfig {
@Autowired
private ClusterConfigurationProperties clusterConfigurationProperties;
@Autowired
private Validator validator;
@Bean
ClusterConfigurationProperties clusterConfigurationProperties() {
return null;
}
@Bean
Validator validator() {
return new Validator();
}
@Bean
RedisConnectionFactory connectionFactory() throws ConfigInvalidException {
if (clusterConfigurationProperties == null)
throw new ConfigInvalidException("Please provide a cluster configuration POJO in context");
validator.validate(clusterConfigurationProperties);
return new JedisConnectionFactory(new RedisClusterConfiguration(clusterConfigurationProperties.getNodes()));
}
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) throws ConfigInvalidException {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory());
redisTemplate.setKeySerializer( new StringRedisSerializer() );
redisTemplate.setHashValueSerializer( new GenericToStringSerializer<>( Object.class ) );
redisTemplate.setValueSerializer( new GenericToStringSerializer<>( Object.class ) );
return redisTemplate;
}
}
这里我期望 ClusterConfigurationProperties POJO 作为应用程序中的 bean,它将使用包装器的接口。
但是为了编译我的包装器,我自己创建了一个空 bean。那么当application使用的时候,会有两个bean,一个application,一个wrapper。
我该如何解决这个问题?
实际上我想要的是在我的客户端应用程序中将集群配置作为一个 bean。为此,我不需要在我的包装器应用程序中声明@autowire clusterconfig。相反应该在方法中将cluster config作为参数,这样client在创建bean的时候会传递cluster config对象。在客户端代码中创建的 bean 应该有创建 redis 连接工厂的代码。
但是我写的所有这些都是为了让我的客户不知道redis。因此,更好的解决方案是使用包装器 class,它采用集群配置 pojo 并创建 redis 连接工厂等。客户端应将此包装器创建为 bean。
spring 和设计模式的概念很差导致我犯了这个错误。
我正在使用 spring 框架创建缓存客户端包装器。这是为我们的应用程序提供缓存层。现在,我们正在使用redis。我发现 spring-data-redis 库非常适合创建我的包装器。
我的应用程序会将配置 POJO 传递给我的包装器,然后使用我将提供的接口。
spring-data-redis 提供了一种使用两个变量访问 redis 的简单方法。
RedisConnectionFactory
RedisTemplate<String, Object>
尽管如此,我会为我的应用程序提供更好的界面,我的界面函数如下:
public Object getValue( final String key ) throws ConfigInvalidException;
public void setValue( final String key, final Object value ) throws ConfigInvalidException;
public void setValueWithExpiry(final String key, final Object value, final int seconds, final TimeUnit timeUnit) throws ConfigInvalidException;
我仍然想提供 RedisConnectionFactory 和 RedisTemplate bean。
我的问题是如何使用此配置 POJO 初始化我的包装器应用程序?
目前我的配置是这样的:
import java.util.List;
public class ClusterConfigurationProperties {
List<String> nodes;
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
我的 AppConfig.java 看起来像这样:
import com.ajio.Exception.ConfigInvalidException;
import com.ajio.configuration.ClusterConfigurationProperties;
import com.ajio.validator.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class AppConfig {
@Autowired
private ClusterConfigurationProperties clusterConfigurationProperties;
@Autowired
private Validator validator;
@Bean
ClusterConfigurationProperties clusterConfigurationProperties() {
return null;
}
@Bean
Validator validator() {
return new Validator();
}
@Bean
RedisConnectionFactory connectionFactory() throws ConfigInvalidException {
if (clusterConfigurationProperties == null)
throw new ConfigInvalidException("Please provide a cluster configuration POJO in context");
validator.validate(clusterConfigurationProperties);
return new JedisConnectionFactory(new RedisClusterConfiguration(clusterConfigurationProperties.getNodes()));
}
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) throws ConfigInvalidException {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory());
redisTemplate.setKeySerializer( new StringRedisSerializer() );
redisTemplate.setHashValueSerializer( new GenericToStringSerializer<>( Object.class ) );
redisTemplate.setValueSerializer( new GenericToStringSerializer<>( Object.class ) );
return redisTemplate;
}
}
这里我期望 ClusterConfigurationProperties POJO 作为应用程序中的 bean,它将使用包装器的接口。
但是为了编译我的包装器,我自己创建了一个空 bean。那么当application使用的时候,会有两个bean,一个application,一个wrapper。
我该如何解决这个问题?
实际上我想要的是在我的客户端应用程序中将集群配置作为一个 bean。为此,我不需要在我的包装器应用程序中声明@autowire clusterconfig。相反应该在方法中将cluster config作为参数,这样client在创建bean的时候会传递cluster config对象。在客户端代码中创建的 bean 应该有创建 redis 连接工厂的代码。
但是我写的所有这些都是为了让我的客户不知道redis。因此,更好的解决方案是使用包装器 class,它采用集群配置 pojo 并创建 redis 连接工厂等。客户端应将此包装器创建为 bean。
spring 和设计模式的概念很差导致我犯了这个错误。