Why can get direct access when the Spring bean instances through annotated @ Autowired / @ Resource interface rather than injected class

Q :

       This problem has troubled me for a long time, this question has been how the interface is injected into the bean? Because only see use @Service injected implementation class serviceImpl, how they get when using the interface, but also calls into the implementation class method, is at what time this interface is automatically injected into it, and the class association and realize the ?

interface

public interface TestService {

    public String test();
}

Implementation class impl

public class TestServiceImpl implements TestService{

    @Override
    public String test() {
        return "TestServiceImpl";
    }
}

Controller call:

@RestController
public class TestCtl {

    @Autowired
    private TestService testService;
    
    @RequestMapping("/test")
    public String test() {
        return testService.test();
    }
}

Request results:

  

Answer :

       Only later did know, and did not inject bean interface, only injected the bean implementation class serviceImpl, the interface only to receive, and here we must say injection principle @ Autowired / @ Resource of the: @Autowired Spring's comment, Autowired default press byType, if finding it more bean, then, and in accordance with byName way than the right, if there are more, then report the anomaly; @Resource is JDK1.6 support annotations, assembled in accordance with the default name (byname) If you do not specify the name attribute, when the notes written on the field, take the default field name, find by name, if the notes written on the attribute setter methods to take default name for assembly. When that matches the name can not be found when assembled in accordance with the type of bean. However, note that if the name attribute if specified, will only be assembled by name.      

       And then for the Controller to obtain an instance of the process: the use of @Autowired, the program finds in the spring container is TestService type of bean, just find one and only one of this type of bean, namely testServiceImpl, so put testServiceImpl automatic assembly to an instance of testService controller in, testService in fact TestServiceImpl implementation class;

If you are using @Resource, it is the first to find the name in the container is testService the bean, but did not find, because the bean container name is TestServiceImpl (@Service if the value is not specified bean property, the bean name is injected class name, if specified, is the name specified), and then look for the type of bean TestService by type, found only had a TestService type bean (ie TestServiceImpl), so we automated assembly instance successful.

 

Note:

byName automatically assembled by the parameter name, the same name and if a bean is another bean Property, automatically assembled.

byType automatically assembled by automatic data type parameter, if a data type of bean and additional data type of a bean property attribute compatible, automatically assembling

Efficiency is @ Autowired / @ Resource almost, but recommended @Resource, because when there are multiple interfaces to achieve direct @Resource be able to specify a class by the name attribute, and @Autowired but also with @Qualifier annotation to use, and @Resource is jdk notes, can be decoupled from the Spring.

 

Q :

If you have more than one interface implementation class, how to know when to obtain an instance via annotations should get a realization of what kind serviceImpl it?

Add an implementation class TestServiceImpl2

@Service
public class TestServiceImpl2 implements TestService{

    @Override
    public String test() {
        return "TestServiceImpl2";
    }
}

Answer :

If the plurality of classes may be implemented in the following two ways to specify which one to use particular implementation:

1, designated by the name of the bean to clear in the end to which class to instantiate

@Autowired requires a combination @Qualifier used, as follows:

    @Autowired
    @Qualifier("testServiceImpl")
    private TestService testService;

@Resource directly to the value specified by the name attribute, but can also be used @Qualifier (somewhat superfluous ...)

    @Resource(name = "testServiceImpl")
    private TestService testService;    

@Resource specify the name value if you do not show, it will automatically name as the name of the instance variable value, so it can be directly written:

   @Resource
    private TestService testServiceImpl;

2, by adding @Primary annotation on the implementation class to specify the default load classes

@Service
@Primary
public class TestServiceImpl2 implements TestService{

    @Override
    public String test() {
        return "TestServiceImpl2";
    }
}

So if if you do not specify the name of the bean, the bean will default to get TestServiceImpl2 when using the @ Autowired / @ Resource obtain an instance, if the bean name specified places specified prevail.

 

Q :

       Why bother to have to call interface, instead of directly calling the bean implementation class is more straightforward serviceImpl of it?

Answer :

1, direct access serviceImpl bean implementation class are possible;

2, add a layer interfaces for reasons: First, AOP settings thought, interfaces to other people call, the caller wanted to know methods and functions, and for the internal logic of how to achieve this method does not care; the second is to reduce the association between each module, loosely coupled, hierarchical procedures, highly scalable, make the program more flexible, in addition to his outstanding contribution in the specification, the essence is the most used in the polymorphic; inheritance only single inheritance, but the interface can achieve more than

3, when the business logic simpler, less change, when the self-use, directly omitted class that implements the interface is more straightforward; otherwise recommended interfaces;

 

Guess you like

Origin www.cnblogs.com/aland-1415/p/11991170.html