title: How spring @autowired works for interface and implementation classes
body: <p>I am new to Java/Spring Boot and am seeing unexpected functionality of a method that is overridden in a UserServiceImpl class. Even though this class is not exported, the overridden method is the one that is being used.   </p>
  
  <p>Basically, I have a UserService Interface class and a UserServiceImpl class for this interface. The UserService Interface has a createUser method declared. The UserServiceImpl then overrides this method and adds additional functionality. </p>
  
  <p>The UserController class then imports the UserService Interface class and calls the createUser method. However, even though the UserServiceImpl is not imported into the UserController class, the overridden createUser method from this class is used. How is it possible for the UserController to know that the createUser method from the interface was overridden if the impl class in which it is overriden is not imported into the UserController?</p>
  
  <p>I have included these classes below:</p>
  
  <p>The UserService Interface:</p>
  
  <pre><code>package sbootproject.service.intrf;
  import sbootproject.shared.dto.UserDto;
  
  public interface UserService {
      UserDto createUser(UserDto user);
  } 
  </code></pre>
  
  <p>The UserService Impl where the createUser method is overridden:</p>
  
  <pre><code>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;
      }
  }
  </code></pre>
  
  <p>And finally, the UserController:</p>
  
  <pre><code>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;
          }
  }
  </code></pre>