How does autowiring work in Spring?

后端 未结 11 1574
执笔经年
执笔经年 2020-11-22 15:35

I\'m a little confused as to how the inversion of control (IoC) works in Spring.

Say I have a service class called UserServic

11条回答
  •  误落风尘
    2020-11-22 16:19

    Standard way:

    @RestController
    public class Main {
        UserService userService;
    
        public Main(){
            userService = new UserServiceImpl();
        }
    
        @GetMapping("/")
        public String index(){
            return userService.print("Example test");
        }
    }
    

    User service interface:

    public interface UserService {
        String print(String text);
    }
    

    UserServiceImpl class:

    public class UserServiceImpl implements UserService {
        @Override
        public String print(String text) {
            return text + " UserServiceImpl";
        }
    }
    

    Output: Example test UserServiceImpl

    That is a great example of tight coupled classes, bad design example and there will be problem with testing (PowerMockito is also bad).

    Now let's take a look at SpringBoot dependency injection, nice example of loose coupling:

    Interface remains the same,

    Main class:

    @RestController
    public class Main {
        UserService userService;
    
        @Autowired
        public Main(UserService userService){
            this.userService = userService;
        }
    
        @GetMapping("/")
        public String index(){
            return userService.print("Example test");
        }
    }
    

    ServiceUserImpl class:

    @Component
    public class UserServiceImpl implements UserService {
        @Override
        public String print(String text) {
            return text + " UserServiceImpl";
        }
    }
    

    Output: Example test UserServiceImpl

    and now it's easy to write test:

    @RunWith(MockitoJUnitRunner.class)
    public class MainTest {
        @Mock
        UserService userService;
    
        @Test
        public void indexTest() {
            when(userService.print("Example test")).thenReturn("Example test UserServiceImpl");
    
            String result = new Main(userService).index();
    
            assertEquals(result, "Example test UserServiceImpl");
        }
    }
    

    I showed @Autowired annotation on constructor but it can also be used on setter or field.

提交回复
热议问题