Переход с весенней загрузки 2 из Spring boot 1.5 с редисом - PullRequest
0 голосов
/ 19 октября 2018

Мне нужно изменить код 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.

1 Ответ

0 голосов
/ 19 октября 2018

Вы разместили @ ConditionalOnMissingBean аннотацию, которая соответствует только тогда, когда в BeanFactory не содержится никаких бинов классов RedisConnectionFactory.Глядя на журнал, мы видим, что вы пытаетесь настроить клиентские библиотеки Lettuce и Jedis:

- Bean method 'redisConnectionFactory' in 'JedisConnectionConfiguration' not loaded because @ConditionalOnMissingBean
- Bean method 'redisConnectionFactory' in 'LettuceConnectionConfiguration' not loaded because @ConditionalOnMissingBean

Но вы должны использовать только одну за раз.Удалите JedisConnectionConfiguration и удалите зависимость jedis, если вы хотите использовать салат и наоборот.

Однако я рекомендую вместо этого использовать Redis Starter:

1. Добавить spring-boot-starter-data-redis maven зависимость

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. Удалить jedis и spring-data-redis maven зависимости

3. Удалить @Аннотации-классификаторы, поскольку вам не требуется больше контроля над процессом выбора autowiring

4. Установите фабрику соединений с помощью setConnectionFactory ()

redisTemplate.setConnectionFactory(connectionFactory);

5. Использовать Redis Starter, предлагающий базовую автоконфигурацию

Удалить redisConnectionFactory() метод.

Ввод автоконфигурируемой RedisConnectionFactory или RedisTemplate экземпляр, как любой другой Spring Bean для подключения к Redis.

6. Использование свойств Red Boot Spring Boot

Spring Boot использует эти значения по умолчаниюRedis свойства, которые вы можете перезаписать в файле свойств:

spring.redis.host=localhost
spring.redis.port=6379

См. здесь для более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...