Spring boot + redis

Я работаю демонстрационным приложением загрузки Spring с интеграцией Redis.

Я сослался на различные ссылки на сайты, но, наконец, я предпочел следовать этому: http://www.baeldung.com/spring-data-redis-tutorial

Мой код почти такой же, как и в приведенной выше ссылке. Единственное изменение состоит в том, что у меня автоматически подключен StudentRepository в моем классе RestController.

Теперь, когда я пытаюсь выполнить maven-install в это время, я получаю ошибку, которая

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentController': Unsatisfied dependency expressed through field 'studentRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentRepositoryImpl' defined in file [/home/klevu/work/Nimesh/Spring Boot Workspace/bootDemo/target/classes/com/example/demo/redis/repository/StudentRepositoryImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.example.demo.redis.repository.StudentRepositoryImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.example.demo.redis.repository.StudentRepositoryImpl

Когда я попытался сделать конструктор общедоступным, он успешно создал сборку. Но я не знаю, делать это здесь или нет. Я думал, что вместо конструктора Autowiring я должен уметь выполнять инъекцию через сеттер. Я также пробовал ниже:

@Autowired
private RedisTemplate<String, Student> redisTemplate;

Но это тоже не работает.

package com.example.demo.redis.repository;

import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import com.example.demo.redis.bean.Student;

@Repository
public class StudentRepositoryImpl implements StudentRepository {

    private static final String KEY = "Student";

    //@Autowired
    private RedisTemplate<String, Student> redisTemplate;

    private HashOperations<String, String, Student> hashOps;

    @Autowired
    private StudentRepositoryImpl(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @PostConstruct
    private void init() {
        hashOps = redisTemplate.opsForHash();
    }

    @Override
    public void saveStudent(Student person) {
        hashOps.put(KEY, person.getId(), person);
    }

    @Override
    public void updateStudent(Student person) {
        hashOps.put(KEY, person.getId(), person);
    }

    @Override
    public Student findStudent(String id) {
        return hashOps.get(KEY, id);
    }

    @Override
    public Map<String, Student> findAllStudents() {
        return hashOps.entries(KEY);
    }

    @Override
    public void deleteStudent(String id) {
        hashOps.delete(KEY, id);
    }
}

RedisConfiguration по умолчанию и код, как показано ниже:

package com.example.demo.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
public class RedisConfiguration {

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        return new JedisConnectionFactory();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(){
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }


}

Основная точка входа в Spring boot объявлена ​​следующим образом:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;

@SpringBootApplication
@EnableMongoRepositories(basePackages = {"com.example.demo.mongo.repository"} )
@EnableRedisRepositories(basePackages = {"com.example.demo.redis.repository"})
public class BootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(BootDemoApplication.class, args);
    }
}

Демо-контроллер для тестирования Redis выглядит следующим образом:

package com.example.demo.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.redis.bean.Student;
import com.example.demo.redis.repository.StudentRepository;

@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping
    public ResponseEntity<Map<String, Student>> index() {
        Map<String, Student> students = studentRepository.findAllStudents();
        return new ResponseEntity<Map<String, Student>>(students, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/{id}")
    public ResponseEntity<Student> getStudentById(@PathVariable("id") String id) {
        Student student = studentRepository.findStudent(id);
        return new ResponseEntity<Student>(student, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<Student> saveStudent(@RequestBody Student student) {
        studentRepository.saveStudent(student);
        return new ResponseEntity<Student>(student, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.PUT, value = "/{id}")
    public ResponseEntity<Student> updateStudent(@RequestBody Student student) {
        studentRepository.updateStudent(student);
        return new ResponseEntity<Student>(student, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
    public ResponseEntity<Student> deleteMessage(@PathVariable("id") String id) {
        studentRepository.deleteStudent(id);
        return new ResponseEntity<Student>(HttpStatus.OK);
    }
}

person Nimesh    schedule 16.08.2017    source источник
comment
Также разместите код studentRepository.   -  person Mehraj Malik    schedule 16.08.2017
comment
пожалуйста, введите код, так как у меня нет доступа к учебнику.   -  person Narendra Jaggi    schedule 16.08.2017
comment
Можете ли вы опубликовать свой код на Github?   -  person diguage    schedule 16.08.2017
comment
Я добавил код. @diguage Я думаю, что этот код содержит все. Дайте мне знать, если вам все еще нужен git.   -  person Nimesh    schedule 16.08.2017
comment
Не уверен, почему в демоверсии, которую вы реализуете, есть это, но попробуйте изменить private StudentRepositoryImpl на public   -  person Darren Forsythe    schedule 16.08.2017
comment
@DarrenForsythe Я изучаю весеннюю загрузку с различными интеграциями, такими как JPA, mongo и Redis. Что-то не так в моей реализации?   -  person Nimesh    schedule 16.08.2017
comment
Конструктор StudentRepositoryImpl является частным. Попробуйте сменить его на public.   -  person Darren Forsythe    schedule 16.08.2017
comment
Да, но я почти скопировал код из данного блога, поэтому меня смущает то, что он объявлен закрытым для синглтона, или я сделал что-то не так.   -  person Nimesh    schedule 16.08.2017
comment
Ошибка буквально заявляется, что существует 0 публичных конструкторов. Блог неправильный.   -  person Darren Forsythe    schedule 16.08.2017


Ответы (3)


Вы устанавливаете конструктор как частный ... измените его на общедоступный

@Autowired
public StudentRepositoryImpl(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
}
person Caio Cascaes    schedule 07.11.2017

Измените следующую конфигурацию Redis:

Ваш оригинал:

@Bean
public RedisTemplate<String, Object> redisTemplate() {
   ...
}

Измените его на:

@Bean
public RedisTemplate<String, ?> redisTemplate(){
    ...
}

Теперь это должно сработать для вас.

person Michael Qin    schedule 17.10.2017

Вы можете использовать Spring Data Redis

Добавьте зависимости:

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

Включить кеширование

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class RedisDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }

}

Добавить кэшируемую аннотацию в методе для кеширования в Redis

   @Cacheable(value = "employee", key = "#id")
    public Employee getEmployee(Integer id) {
        log.info("Get Employee By Id: {}", id);
        Optional<Employee> employeeOptional = employeeRepository.findById(id);
        if (!employeeOptional.isPresent()) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Id Not foud");
        }
        return employeeOptional.get();
    }
person Prateek Kapoor    schedule 03.04.2021