【问题标题】:How spring @autowired works for interface and implementation classesspring @autowired 如何用于接口和实现类
【发布时间】:2018-12-16 04:41:39
【问题描述】:

我是 Java/Spring Boot 的新手,我看到了在 UserServiceImpl 类中被覆盖的方法的意外功能。即使这个类没有被导出,被覆盖的方法是被使用的。

基本上,我有一个 UserService 接口类和一个用于此接口的 UserServiceImpl 类。 UserService 接口声明了一个 createUser 方法。 UserServiceImpl 然后覆盖此方法并添加附加功能。

UserController 类然后导入 UserService 接口类并调用 createUser 方法。但是,即使没有将 UserServiceImpl 导入到 UserController 类中,也会使用该类中重写的 createUser 方法。如果重写的 impl 类没有导入到 UserController 中,UserController 怎么可能知道接口中的 createUser 方法被重写了?

我在下面包含了这些类:

用户服务接口:

package sbootproject.service.intrf;
import sbootproject.shared.dto.UserDto;

public interface UserService {
    UserDto createUser(UserDto user);
} 

createUser 方法被覆盖的 UserService Impl:

package sbootproject.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import sbootproject.UserRepository;
import sbootproject.entity.UserEntity;
import sbootproject.service.intrf.UserService;
import sbootproject.shared.dto.UserDto;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDto createUser(UserDto user) {       
        UserEntity userEntity = new UserEntity();
        BeanUtils.copyProperties(user, userEntity);     
        userEntity.setEncryptedPassword("test");
        userEntity.setUserId("testUserId");     
        UserEntity storedUserDetails = userRepository.save(userEntity);     
        UserDto returnValue = new UserDto();
        BeanUtils.copyProperties(storedUserDetails, returnValue);       
        return returnValue;
    }
}

最后是用户控制器:

package sbootproject.controller;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import sbootproject.model.request.UserDetailsRequestModel;
import sbootproject.model.response.UserRest;
import sbootproject.service.intrf.UserService;
import sbootproject.shared.dto.UserDto;

@RestController   
public class UserController {

    @Autowired
    UserService userService;    

        @PostMapping(path="/postMethod")
        public UserRest createUser(@RequestBody UserDetailsRequestModel userDetails) {  
            UserRest returnValue = new UserRest();          
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(userDetails, userDto);         
            UserDto createdUser = userService.createUser(userDto);
            BeanUtils.copyProperties(createdUser, returnValue);         
            return returnValue;
        }
}

【问题讨论】:

    标签: java spring-mvc spring-boot interface spring-data-jpa


    【解决方案1】:

    如果接口只有一个实现,并且使用@Component 或@service 注释并启用了Spring 的组件扫描,则Spring 框架可以找到(接口,实现)对。

    @限定符

    如果你有多个实现,那么你需要@Qualifier 注解来注入正确的实现,以及@Autowired 注解。

    【讨论】:

      【解决方案2】:

      Spring 在上下文中搜索 UserService 的实现,只找到一个 UserServiceImpl,如果有 2 个,您将遇到可以使用配置文件或 Qualifier 修复的问题

      【讨论】:

      • Spring 知道是因为那是唯一实现接口的类吗?
      猜你喜欢
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      • 2015-07-18
      • 2014-07-16
      • 2013-01-29
      • 1970-01-01
      相关资源
      最近更新 更多