首页 > 解决方案 > Spring Boot中的Redis,保留redis模板

问题描述

我有一个项目的问题。我正在用spring和redis创建一个非常原始的聊天程序。

我将 redis 连接作为 Spring Bean:

private HashOperations hashOps;

@Autowired
public UserRepositoryImpl(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
}

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

直到这里一切似乎都正常工作,并且 hashhops 被声明为模板。但现在我打电话

 public boolean createUser(User user){
        if(user.getName().isEmpty() || user.getPassword().isEmpty()){
            return false;
        }
        user.setStatus("");
        if(hashOps.putIfAbsent(KEY, user.getName(), user)){
            List<String> following = null;
            hashOps.put("isFollowing", user.getName(),following);
            FollowListImpl fLI = new FollowListImpl(this.redisTemplate);
            fLI.follow("global", user);
            return true;
        }
        return false;
    }

在 redis 中创建第一个数据(用户)。该方法与声明的类在同一个类中,hashOpshasOps现在为 NULL。但是当我使用其他人的项目时,hashOps即使通过方法调用,解决方案也会保留模板。

Redis 在主类(starter 类)中是 Connected 的:

@SpringBootApplication
public class CommunicatorApplication {

@Bean
public JedisConnectionFactory getConnectionFactory() {
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setPort(6379);
    jedisConnectionFactory.setHostName("localhost");
    jedisConnectionFactory.setPassword("");
    return jedisConnectionFactory;
}

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

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

现在的问题是,当 spring 正常工作时,它实际上是如何保留hashOps的,我做错了什么,它没有保留在我的代码中。

createUser在这里打电话:

  @Controller
public class LoginController {
     @RequestMapping(value = "/login", params = "btnRegister")
    public String loginRegister(@ModelAttribute Login login, Model model){
        model.addAttribute("login", login != null ? login : new Login());
        UserRepositoryImpl user = new UserRepositoryImpl(null);
        user.createUser(login.getName(),login.getPassword());
        System.out.println(user.findUser(login.getName()));
        return "login";
    }

标签: javaspringredis

解决方案


这一行正在实例化一个新的实例UserRepositoryImpl

UserRepositoryImpl user = new UserRepositoryImpl(null);

您正在创建的这个实例不会以任何方式附加到 Spring。你甚至在这里明确地null作为redisTemplate参数传递,所以这当然是行不通的。

您需要使用UserRepositoryImpl由 Spring 创建和管理的实例。为此,您需要指示 Spring 将实例连接到LoginController. 完成此操作的一种方法是使用@Autowired注释,如下所示:

@Controller
public class LoginController {
    @Autowired
    private UserRepositoryImpl userRepository;

    @RequestMapping(value = "/login", params = "btnRegister")
    public String loginRegister(@ModelAttribute Login login, Model model){
        model.addAttribute("login", login != null ? login : new Login());
        userRepository.createUser(login.getName(),login.getPassword());
        System.out.println(userRepository.findUser(login.getName()));
        return "login";
    }

推荐阅读