Spring and interfaces

I read throughout how Spring encourages you to use interfaces in your code. I do not see this. There is no concept of an interface in your Spring xml configuration. What part of Spring really encourages you to use interfaces (other than documents)?

+19
java spring
Nov 01 '08 at 23:35
source share
8 answers

When you define an interface for your classes, it helps with dependency injection. Your Spring configuration files have nothing about the interfaces themselves in them - you just specify the class name.

But if you want to introduce another class that offers "equivalent" functionality, using an interface really helps.

For example, saying that you have a class that parses the contents of a website, and you enter it using Spring. If the classes you enter in order to find out what the actual class is, then to change it, you will have to change the whole code to use another specific class. But if you created the Analyzer interface, you can just as easily insert the original DefaultAnalyzer as you could mock DummyAnalyzer or even another that does essentially the same thing as PageByPageAnalyzer or something else. To use one of them, you just need to change the class name that you enter in the Spring configuration files, and not go through the classes that change the code.

It took me about one and a half projects before I really started to see the utility. Like most things (in corporate languages) that eventually become useful, at first it seems like a pointless addition of work until your project starts to grow, and then you know how much time you saved by doing a little more work.

+25
Nov 02 '08 at 5:04
source share

The dependency inversion principle explains this well. In particular, Figure 4.

but. High-level modules should not be dependent on low-level modules. Both should depend on abstractions.

B. Abstraction should not depend on details. Details should depend on abstractions.

Translation of examples from the above link in java:

 public class Copy { private Keyboard keyboard = new Keyboard(); // concrete dependency private Printer printer = new Printer(); // concrete dependency public void copy() { for (int c = keyboard.read(); c != KeyBoard.EOF) { printer.print(c); } } } 

Now with dependency inversion:

 public class Copy { private Reader reader; // any dependency satisfying the reader interface will work private Writer writer; // any dependency satisfying the writer interface will work public void copy() { for (int c = reader.read(); c != Reader.EOF) { writer.write(c); } } public Copy(Reader reader, Writer writer) { this.reader = reader; this.writer = writer; } } 

Copy now supports more than just copying from the keyboard to the printer.

It is able to copy from any Reader to any Writer without any changes to its code.

And now with Spring:

 <bean id="copy" class="Copy"> <constructor-arg ref="reader" /> <constructor-arg ref="writer" /> </bean> <bean id="reader" class="KeyboardReader" /> <bean id="writer" class="PrinterWriter" /> 

or perhaps:

 <bean id="reader" class="RemoteDeviceReader" /> <bean id="writer" class="DatabaseWriter" /> 
+31
Nov 02 '08 at 0:45
source share

Most of the answers here are the “You can easily replace the implementations” form, but I think they cannot answer why? part. To this, I think that the answer is almost completely verified. Regardless of whether you use Spring or any other IOC structure, using Injection Dependency makes your code easier to test. In the case of, for example, a writer, not a PrinterWriter, you can break down the Writer interface in Unit test and make sure your code calls it the way you expect. If you directly depend on the implementation of the class, the only option is to go to the printer and check it, which is not very automated. In addition, if you depend on the result of calling the class, the inability to Mock, this may prevent you from reaching all the code paths in your test, thereby reducing their quality (potentially). Simply put, you have to separate the graph creation object from the application logic. This makes your code easier to test.

+9
Nov 03 '08 at 23:42
source share

You might want to try using it for yourself to be able to see this better, it may not be clear from the docs how Spring encourages the use of the interface.

Here are some examples:

  • Suppose you are writing a class that needs to be read from a resource (for example, a file), which can be referenced in several ways (for example, in the class path, the absolute path to the file as a URL, etc.). You want to define the org.springframework.core.io.Resource (interface) property in your class. Then, in the Spring configuration file, you simply select the actual implementation class (e.g. org.springframework.core.io.ClassPathResource , org.springframework.core.io.FileSystemResource , org.springframework.core.io.UrlResource , etc.). Spring basically functions as an extremely general factory.

  • If you want to use Spring AOP integration (for example, to add transaction hooks), you will need to define interfaces pretty much. You define the intercept points in the Spring configuration file, and Spring creates a proxy for you based on your interface.

These are examples that I personally encounter. I am sure there is much more.

+2
Nov 01 '08 at 23:50
source share

Easily create proxies from interfaces.

if you look at any spring application, you will see service and persistence interfaces. that the idiom spring certainly encourages the use of interfaces. he does not become more explicit than that.

+1
Nov 14 '08 at 0:13
source share

No one mentions yet that in many cases it will not be necessary to create an interface in order to quickly implement the switch, because there simply will not be more than one implementation class.

When interfaces are created unnecessarily, classes are created in pairs (interface plus implementation), adding unnecessary template interfaces and creating potential misunderstandings of dependencies, because in XML configuration files, components sometimes refer to their interface, and sometimes to implement it without any consequences during execution, but incompatible with code conventions.

+1
Jul 09 '14 at 2:09
source share

If you don’t use interfaces, you risk auto-device failure : Sometime Spring creates a proxy class for Bean. This proxy class is not a child of the service implementation class , but it reimplementes all of its interfaces. Spring will try to auto-validate instances of this Bean, however this Proxy class is not compatible with the Bean class. Thus, declaring a field with a Bean class can result in "unsafe field assignment" exceptions.

You cannot reasonably know when Spring is going to the proxy server (and should not), therefore, to protect yourself from these surprises, your best way is to declare an interface and use this interface when declaring fields with auto-negotiation.

+1
May 19 '15 at 13:53
source share

Spring won't make you use interfaces anywhere, it's just good practice. If you have a bean that has some properties that are interfaces instead of specific classes, you can simply disable some objects with layouts that implement the same interface, which is useful for certain test cases.

If you use, for example, Hibernate support clans, you can define an interface for your DAO, and then implement it separately; the advantage of having an interface is that you can configure it with Spring hooks, which will allow you to simplify the code; you don’t have to write any Cibing HibernateExceptions code and close the session in the final segment, and you also don’t need to define any transactions programmatically, you just set it all up declaratively using Spring.

When you write fast and dirty applications, you can implement some simple DAOs using JDBC or some simple structure that you cannot use in the final version; you can easily disable these components if they implement some common interfaces.

0
Nov 04 '08 at 19:31
source share



All Articles