The annotation @Autowired
is not instantiating an interface.
There is no way to instantiate an interface since the interface is just a "contract" (in Java 8 there are methods default with concrete implementations but this is subject to another conversation). The closest you can get to "instantiating an interface" in Java is to instantiate an anonymous class that implements a interface as per Piovezan's response . But that's not what Spring is doing in this example.
Spring actually creates an instance of ThingRepositoryImpl
. Additionally the framework can also wrap the implementation with proxies or do weaving to provide aspects such as transaction control for the application.
In this example you are using the interface as reference type . The idea is to hide the implementation to make the application design more flexible. ThingRepository
is used as reference type for the same reason that we usually expose the interface List
and not one of its concrete types as ArrayList
in the APIs:
List<String> list = buildList();
public List<String> buildList() {
List<String> list = new ArrayList<>();
// você pode trocar a implementacao para LinkedList sem
// mudanças no restante da aplicação
return list;
}
Assume that ThingRepositoryImpl
today implements persistence using the MySQL database. At one time you may want to use MongoDB instead of MySQL (or who knows MySQL for some clients and MongoDB for others). Using the ThingRepository
interface as the reference type you are hiding the actual implementation of the service. This way you can always create a new implementation of ThingRepository
(e.g., ThingRepositoryMongoDBImpl
) and replace it with Spring transparently for the classes that currently depend on that service. This would not be possible if you refer to the ThingRepositoryImpl
class directly, in which case you would have to modify the "client" classes.
In short, there is a maximum " Program for interface, not for implementation that marries well with the Dependency Injection service provided by Spring. Combining both things the design of your application becomes more flexible (i.e., it becomes easier to evolve the application).