Мне нужно изменить код Redis, чтобы он работал с новым SpringBoot 2.0.3, в настоящее время при запуске Tomcat 9.0.12 (не запускать SpringBoot как Jar - причина бизнес-потребностей) я получаю следующую ошибку:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method vehicleHistoryCacheManager in somePath.config.UfCacheConfig
required a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' that could not be found.
- Bean method 'redisConnectionFactory' in 'JedisConnectionConfiguration' not loaded because @ConditionalOnMissingBean
(types: org.springframework.data.redis.connection.RedisConnectionFactory; SearchStrategy: all)
beans of type 'org.springframework.data.redis.connection.RedisConnectionFactory' redisConnectionFactory
- Bean method 'redisConnectionFactory' in 'LettuceConnectionConfiguration' not loaded because @ConditionalOnMissingBean
(types: org.springframework.data.redis.connection.RedisConnectionFactory; SearchStrategy: all)
found beans of type 'org.springframework.data.redis.connection.RedisConnectionFactory' redisConnectionFactory
Action:
Consider revisiting the conditions above or defining a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' in your configuration.
19-Oct-2018 13:43:22.142 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/motoPolicy]]
(...)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'technicalController'
defined in file [somePath\TecController.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'ufCacheServiceImpl'
defined in URL [jar:file:/someName.jar!/somePath/UfCacheServiceImpl.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'vehicleHistoryCacheManager' defined in class path resource
[somePath/config/UfCacheConfig.class]:
Unsatisfied dependency expressed through method 'vehicleHistoryCacheManager' parameter 0;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=vehicleTemplate)}
(...)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ufgCacheServiceImpl'
defined in URL [jar:file:/uf.jar!/somePath/UfgCacheServiceImpl.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'vehicleHistoryCacheManager' defined in class path resource
[somePath/config/UfCacheConfig.class]:
Unsatisfied dependency expressed through method 'vehicleHistoryCacheManager' parameter 0;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=vehicleTemplate)}
(...)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'vehicleHistoryCacheManager' defined in class path resource
[somePath/config/UfCacheConfig.class]:
Unsatisfied dependency expressed through method 'vehicleHistoryCacheManager' parameter 0;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=vehicleTemplate)}
(...)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=vehicleTemplate)}
(...)
19-Oct-2018 13:43:22.162 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method manageApp
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/motoPolicy]]
(...)
[2018-10-19 01:43:22,176] Artifact motoPolicy-web:war exploded: Error during artifact deployment. See server log for details.
(...)
19-Oct-2018 13:43:22.162 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method createStandardContext
javax.management.RuntimeOperationsException: Exception invoking method manageApp
(...)
Caused by: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/motoPolicy]]
(...)
Мои зависимости от Redis в pom:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
Вот конфигурация redis:
@Configuration
class RedisConfig {
@Value("${ufg.redis.host}") // 127.0.0.1
private String hostName;
@Value("${ufg.redis.port}") // 6379
private int port;
@Bean
LettuceConnectionFactory redisConnectionFactory() {
LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory();
redisConnectionFactory.setHostName(hostName);
redisConnectionFactory.setPort(port);
return redisConnectionFactory;
}
@Bean
ObjectMapper redisObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new Jdk8Module());
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
objectMapper.setDateFormat(new ISO8601DateFormat());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
}
Вот класс конфигурации:
@Slf4j
@Configuration
@EnableCaching
public class UfCacheConfig {
public static final String VEHICLE_HISTORY_CACHE_MANAGER = "vehicleHistoryCacheManager";
public static final String VEHICLE_HISTORY_CACHE = "vehicleHistoryCache";
public static final String VEHICLE_GENERATOR_NAME = "vehicleKeyGenerator";
public static final String PERSON_HISTORY_CACHE_MANAGER = "personHistoryCacheManager";
public static final String PERSON_HISTORY_CACHE = "personHistoryCache";
public static final String PERSON_GENERATOR_NAME = "personKeyGenerator";
@Value("${ufg.cache.expiration.validity.minutes}")
private int expirationValidityMinutes;
@Bean(value ="vehicleTemplate")
public RedisTemplate<String, GetVehicleInsuranceHistoryResponse> vehicleTemplate(RedisConnectionFactory redisConnectionFactory,
@Qualifier("redisObjectMapper") ObjectMapper objectMapper) {
RedisTemplate<String, GetVehicleInsuranceHistoryResponse> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
@Primary
@Bean(name = VEHICLE_HISTORY_CACHE_MANAGER)
public CacheManager vehicleHistoryCacheManager(@Qualifier("vehicleTemplate") RedisConnectionFactory redisConnectionFactory) {
Duration expiration = Duration.ofSeconds(expirationValidityMinutes * 60);
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(expiration)).build();
}
@Bean(value ="personTemplate")
public RedisTemplate<String, GetPersonInsuranceHistoryResponse> redisTemplate(RedisConnectionFactory redisConnectionFactory,
@Qualifier("redisObjectMapper") ObjectMapper objectMapper) {
RedisTemplate<String, GetPersonInsuranceHistoryResponse> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
@Bean(name = PERSON_HISTORY_CACHE_MANAGER)
public CacheManager personHistoryCacheManager(@Qualifier("personTemplate") RedisConnectionFactory redisConnectionFactory) {
Duration expiration = Duration.ofSeconds(expirationValidityMinutes * 60);
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(expiration)).build();
}
@Bean(name = VEHICLE_GENERATOR_NAME)
public KeyGenerator vehicleKeyGenerator() {
return (o, method, objects) -> new VehicleKeyGenerator((GetVehicleInsuranceHistoryRequest) objects[0]).generate();
}
@Bean(name = PERSON_GENERATOR_NAME)
public KeyGenerator personKeyGenerator() {
return (o, method, objects) -> new PersonKeyGenerator((GetPersonInsuranceHistoryRequest) objects[0]).generate();
}
private static <T> RedisTemplate<String, T> createTemplate(Class<T> clazz, RedisConnectionFactory redisConnectionFactory, ObjectMapper objectMapper) {
RedisTemplate<String, T> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
Jackson2JsonRedisSerializer<T> serializer = new Jackson2JsonRedisSerializer<>(clazz);
serializer.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(serializer);
return redisTemplate;
}
}
Вот класс обслуживания, которыйупоминается в трассировке стека:
@Slf4j
@Service
public class UfCacheServiceImpl implements UfCacheService {
private CacheManager vehicleCacheManager;
private CacheManager personCacheManager;
@Autowired
public UfCacheServiceImpl(@Qualifier(VEHICLE_HISTORY_CACHE_MANAGER) CacheManager vehicleCacheManager,
@Qualifier(PERSON_HISTORY_CACHE_MANAGER) CacheManager personCacheManager) {
this.vehicleCacheManager = vehicleCacheManager;
this.personCacheManager = personCacheManager;
}
@Override
public void clear() {
log.info("Clearing ufg cache");
vehicleCacheManager.getCache(VEHICLE_HISTORY_CACHE).clear();
personCacheManager.getCache(PERSON_HISTORY_CACHE).clear();
}
}
Как видите, я использовал такие вещи, как, но Redis не работает:
@Bean(value ="vehicleTemplate")
@Qualifier("vehicleTemplate")
РЕДАКТИРОВАТЬ:
Относительно ответа Boris
: Единственное, что я могу найти (во всем проекте) с такими фразами, как jedis
или Jedis
, это зависимости pom.Когда я их удаляю, вывод изменится на:
Parameter 0 of method vehicleHistoryCacheManager in somePackages.config.UfCacheConfig required a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' that could not be found.
- Bean method 'redisConnectionFactory' not loaded because @ConditionalOnClass did not find required class 'redis.clients.jedis.Jedis'
- Bean method 'redisConnectionFactory' in 'LettuceConnectionConfiguration' not loaded because @ConditionalOnMissingBean (types: org.springframework.data.redis.connection.RedisConnectionFactory;
SearchStrategy: all) found beans of type 'org.springframework.data.redis.connection.RedisConnectionFactory' redisConnectionFactory
Я не смог найти такую вещь, как JedisConnectionConfiguration
, чтобы удалить ее.
После комментирования зависимостей в pom я не смог найти фразуjedis
во внешних библиотеках.
Я видел, что в версии с spring-boot-starter-parent
(в главном родительском pom) в External Libraries
у меня есть только spring-data-redis
2.0.8.