What's the benefit of having Jersey instantiating components - java

All of the code samples of Spring Boot and Jersey that I have seen register their components with Jersey by passing the component's class.
From here:
public static class JerseyServletConfig extends ResourceConfig {
public JerseyServletConfig() {
register(RequestContextFilter.class);
packages("com.github.cthiebault");
register(LoggingFilter.class);
}
}
Or here:
register(ApiListingResource.class);
ResourceConfig's javadoc says:
Register an instance of a custom JAX-RS component (such as an
extension provider or a feature meta-provider) to be instantiated and
used in the scope of this configurable context.
My questions are:
What is the benefit of letting those resources being instantiated by Jersey?
If we should let Jersey manage those components, why does it still provides a register(Object component) method, why not keep it limited to register(Class<?> componentClass)?
When should we send our own instances instead of letting Jersey instantiating our class?

To start, Dependency Injection is a GoodThing(tm) in general - it allows for separating concerns and it can greatly simplify testing. In general separating object creation from object use gives benefits around separating business/application logic (i.e. object use) from implementation concerns (deciding what objects are wired together).
Allowing Jersey to manage your resources / components is also a GoodThing(tm). It's a part of what Jersey is for. If you allow Jersey to manage your resource lifecycle then you have less code to write / maintain and the code which you do end up writing / maintaining becomes more about what your application does and less about how your objects fit together.
Jersey provides a standard lifecycle, which gives you a convention that allows developers a mental framework to work in - making it easier for new developers to join and existing developers to switch between applications. The lifecycle can be configured if need be, which allows your special-snowflake application to have special-snowflake behaviour if necessary.
The register(Object) method is an example of how you can opt-out of Jersey controlling a component's lifecycle. You may want to do that for lots of reasons, but you should generally look to avoid doing it - let the library do its job. Examples of exceptional cases would be if you're integrating with some legacy code which, for obscure/arcane reasons of its own, means that some crucial class must be an application-level singleton. There may even be some non-legacy reasons why you only want a single instance of something in your application - object mappers were always a good example of this. Typically, you'd use JSR-330 support for that nowadays but there might be some cases where that's not possible.
By integrating with JSR-330, you can also provide custom named scopes for some objects - which allows you to control how Jersey creates and uses objects while also revealing what you're intending (via the scope name). This generally provides a clean structure which is intention-revealing rather than intention-hiding.

Related

Why is Spring's ApplicationContext.getBean with Interface considered bad? [duplicate]

I asked a general Spring question: Auto-cast Spring Beans and had multiple people respond that calling Spring's ApplicationContext.getBean() should be avoided as much as possible. Why is that?
How else should I gain access to the beans I configured Spring to create?
I'm using Spring in a non-web application and had planned on accessing a shared ApplicationContext object as described by LiorH.
Amendment
I accept the answer below, but here's an alternate take by Martin Fowler who discusses the merits of Dependency Injection vs. using a Service Locator (which is essentially the same as calling a wrapped ApplicationContext.getBean()).
In part, Fowler states, "With service locator the application class asks for it [the service] explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control.
Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it [Inversion of Control] unless I need it. This isn't to say it's a bad thing, just that I think it needs to justify itself over the more straightforward alternative."
I mentioned this in a comment on the other question, but the whole idea of Inversion of Control is to have none of your classes know or care how they get the objects they depend on. This makes it easy to change what type of implementation of a given dependency you use at any time. It also makes the classes easy to test, as you can provide mock implementations of dependencies. Finally, it makes the classes simpler and more focused on their core responsibility.
Calling ApplicationContext.getBean() is not Inversion of Control! While it's still easy to change what implemenation is configured for the given bean name, the class now relies directly on Spring to provide that dependency and can't get it any other way. You can't just make your own mock implementation in a test class and pass that to it yourself. This basically defeats Spring's purpose as a dependency injection container.
Everywhere you want to say:
MyClass myClass = applicationContext.getBean("myClass");
you should instead, for example, declare a method:
public void setMyClass(MyClass myClass) {
this.myClass = myClass;
}
And then in your configuration:
<bean id="myClass" class="MyClass">...</bean>
<bean id="myOtherClass" class="MyOtherClass">
<property name="myClass" ref="myClass"/>
</bean>
Spring will then automatically inject myClass into myOtherClass.
Declare everything in this way, and at the root of it all have something like:
<bean id="myApplication" class="MyApplication">
<property name="myCentralClass" ref="myCentralClass"/>
<property name="myOtherCentralClass" ref="myOtherCentralClass"/>
</bean>
MyApplication is the most central class, and depends at least indirectly on every other service in your program. When bootstrapping, in your main method, you can call applicationContext.getBean("myApplication") but you should not need to call getBean() anywhere else!
Reasons to prefer Service Locator over Inversion of Control (IoC) are:
Service Locator is much, much easier for other people to following in your code. IoC is 'magic' but maintenance programmers must understand your convoluted Spring configurations and all the myriad of locations to figure out how you wired your objects.
IoC is terrible for debugging configuration problems. In certain classes of applications the application will not start when misconfigured and you may not get a chance to step through what is going on with a debugger.
IoC is primarily XML based (Annotations improve things but there is still a lot of XML out there). That means developers can't work on your program unless they know all the magic tags defined by Spring. It is not good enough to know Java anymore. This hinders less experience programmers (ie. it is actually poor design to use a more complicated solution when a simpler solution, such as Service Locator, will fulfill the same requirements). Plus, support for diagnosing XML problems is far weaker than support for Java problems.
Dependency injection is more suited to larger programs. Most of the time the additional complexity is not worth it.
Often Spring is used in case you "might want to change the implementation later". There are other ways of achieving this without the complexity of Spring IoC.
For web applications (Java EE WARs) the Spring context is effectively bound at compile time (unless you want operators to grub around the context in the exploded war). You can make Spring use property files, but with servlets property files will need to be at a pre-determined location, which means you can't deploy multiple servlets of the same time on the same box. You can use Spring with JNDI to change properties at servlet startup time, but if you are using JNDI for administrator-modifiable parameters the need for Spring itself lessens (since JNDI is effectively a Service Locator).
With Spring you can lose program Control if Spring is dispatching to your methods. This is convenient and works for many types of applications, but not all. You may need to control program flow when you need to create tasks (threads etc) during initialization or need modifiable resources that Spring didn't know about when the content was bound to your WAR.
Spring is very good for transaction management and has some advantages. It is just that IoC can be over-engineering in many situations and introduce unwarranted complexity for maintainers. Do not automatically use IoC without thinking of ways of not using it first.
It's true that including the class in application-context.xml avoids the need to use getBean. However, even that is actually unnecessary. If you are writing a standalone application and you DON'T want to include your driver class in application-context.xml, you can use the following code to have Spring autowire the driver's dependencies:
public class AutowireThisDriver {
private MySpringBean mySpringBean;
public static void main(String[] args) {
AutowireThisDriver atd = new AutowireThisDriver(); //get instance
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"/WEB-INF/applicationContext.xml"); //get Spring context
//the magic: auto-wire the instance with all its dependencies:
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(atd,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
// code that uses mySpringBean ...
mySpringBean.doStuff() // no need to instantiate - thanks to Spring
}
public void setMySpringBean(MySpringBean bean) {
this.mySpringBean = bean;
}
}
I've needed to do this a couple of times when I have some sort of standalone class that needs to use some aspect of my app (eg for testing) but I don't want to include it in application-context because it is not actually part of the app. Note also that this avoids the need to look up the bean using a String name, which I've always thought was ugly.
One of the coolest benefits of using something like Spring is that you don't have to wire your objects together. Zeus's head splits open and your classes appear, fully formed with all of their dependencies created and wired-in, as needed. It's magical and fantastic.
The more you say ClassINeed classINeed = (ClassINeed)ApplicationContext.getBean("classINeed");, the less magic you're getting. Less code is almost always better. If your class really needed a ClassINeed bean, why didn't you just wire it in?
That said, something obviously needs to create the first object. There's nothing wrong with your main method acquiring a bean or two via getBean(), but you should avoid it because whenever you're using it, you're not really using all of the magic of Spring.
The motivation is to write code that doesn't depend explicitly on Spring. That way, if you choose to switch containers, you don't have to rewrite any code.
Think of the container as something is invisible to your code, magically providing for its needs, without being asked.
Dependency injection is a counterpoint to the "service locator" pattern. If you are going to lookup dependencies by name, you might as well get rid of the DI container and use something like JNDI.
Using #Autowired or ApplicationContext.getBean() is really the same thing. In both ways you get the bean that is configured in your context and in both ways your code depends on spring.
The only thing you should avoid is instantiating your ApplicationContext. Do this only once! In other words, a line like
ApplicationContext context = new ClassPathXmlApplicationContext("AppContext.xml");
should only be used once in your application.
One of Spring premises is avoid coupling. Define and use Interfaces, DI, AOP and avoid using ApplicationContext.getBean() :-)
One of the reasons is testability. Say you have this class:
interface HttpLoader {
String load(String url);
}
interface StringOutput {
void print(String txt);
}
#Component
class MyBean {
#Autowired
MyBean(HttpLoader loader, StringOutput out) {
out.print(loader.load("http://stackoverflow.com"));
}
}
How can you test this bean? E.g. like this:
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
// execution
new MyBean(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get, result::append);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
Easy, right?
While you still depend on Spring (due to the annotations) you can remove you dependency on spring without changing any code (only the annotation definitions) and the test developer does not need to know anything about how spring works (maybe he should anyway, but it allows to review and test the code separately from what spring does).
It is still possible to do the same when using the ApplicationContext. However then you need to mock ApplicationContext which is a huge interface. You either need a dummy implementation or you can use a mocking framework such as Mockito:
#Component
class MyBean {
#Autowired
MyBean(ApplicationContext context) {
HttpLoader loader = context.getBean(HttpLoader.class);
StringOutput out = context.getBean(StringOutput.class);
out.print(loader.load("http://stackoverflow.com"));
}
}
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
ApplicationContext context = Mockito.mock(ApplicationContext.class);
Mockito.when(context.getBean(HttpLoader.class))
.thenReturn(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get);
Mockito.when(context.getBean(StringOutput.class)).thenReturn(result::append);
// execution
new MyBean(context);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
This is quite a possibility, but I think most people would agree that the first option is more elegant and makes the test simpler.
The only option that is really a problem is this one:
#Component
class MyBean {
#Autowired
MyBean(StringOutput out) {
out.print(new HttpLoader().load("http://stackoverflow.com"));
}
}
Testing this requires huge efforts or your bean is going to attempt to connect to stackoverflow on each test. And as soon as you have a network failure (or the admins at stackoverflow block you due to excessive access rate) you will have randomly failing tests.
So as a conclusion I would not say that using the ApplicationContext directly is automatically wrong and should be avoided at all costs. However if there are better options (and there are in most cases), then use the better options.
The idea is that you rely on dependency injection (inversion of control, or IoC). That is, your components are configured with the components they need. These dependencies are injected (via the constructor or setters) - you don't get then yourself.
ApplicationContext.getBean() requires you to name a bean explicitly within your component. Instead, by using IoC, your configuration can determine what component will be used.
This allows you to rewire your application with different component implementations easily, or configure objects for testing in a straightforward fashion by providing mocked variants (e.g. a mocked DAO so you don't hit a database during testing)
Others have pointed to the general problem (and are valid answers), but I'll just offer one additional comment: it's not that you should NEVER do it, but rather that do it as little as possible.
Usually this means that it is done exactly once: during bootstrapping. And then it's just to access the "root" bean, through which other dependencies can be resolved. This can be reusable code, like base servlet (if developing web apps).
There is another time when using getBean makes sense. If you're reconfiguring a system that already exists, where the dependencies are not explicitly called out in spring context files. You can start the process by putting in calls to getBean, so that you don't have to wire it all up at once. This way you can slowly build up your spring configuration putting each piece in place over time and getting the bits lined up properly. The calls to getBean will eventually be replaced, but as you understand the structure of the code, or lack there of, you can start the process of wiring more and more beans and using fewer and fewer calls to getBean.
I've only found two situations where getBean() was required:
Others have mentioned using getBean() in main() to fetch the "main" bean for a standalone program.
Another use I have made of getBean() are in situations where an interactive user configuration determines the bean makeup for a particular situation. So that, for instance, part of the boot system loops through a database table using getBean() with a scope='prototype' bean definition and then setting additional properties. Presumably, there is a UI that adjusts the database table that would be friendlier than attempting to (re)write the application context XML.
however, there are still cases where you need the service locator pattern.
for example, i have a controller bean, this controller might have some default service beans, which can be dependency injected by configuration.
while there could also be many additional or new services this controller can invoke now or later, which then need the service locator to retrieve the service beans.
You should to use: ConfigurableApplicationContext instead of for ApplicationContext

What does it mean to "proxy a bean"?

At work and online I keep hearing the term "proxy" with respect to enterprise Java development. For example, metrics-spring uses this phrase:
This module does the following things:
Creates metrics and proxies beans which contain methods annotated with
#Timed, #Metered, #ExceptionMetered, and #Counted [emphasis mine]
I'm unfamiliar with a lot of the language in the Java ecosystem of frameworks and libraries. I feel like I have a good understanding of what a bean is, but I'm still not clear about how one would proxy a bean.
What does it mean to proxy a bean?
Typically, you have a bean like
Bean bean = new Bean(); // actually created by the context
With this, you can do anything that the Bean class declares as behavior (invoke its methods).
There are times where it would be nice if you could, for example, track how long a method invocation takes.
You could do
long start = .. // get start time
bean.invoke();
long end = .. // get end time
// end - start
But doing this for each method invocation sucks. So, instead, patterns, architectures, and styles like Aspect Oriented Programming exist.
Instead of the Bean above, you'd have
Bean bean = new TimingBean(new Bean()); // again done by the context
where the TimingBean is a proxy type that extends and implements all the types that Bean extends and implements. For all intents and purposes it is a Bean, but it adds a bunch of additional behavior before delegating each invocation to the Bean object. In this case, it would track how long each of Bean's method's took to execute.
Basic Spring uses JDK proxies and CGLIB proxies. Here are some differences between them.
It uses this for its scheduling and asynchronous invocations. It uses it for transactional support with databases. It uses it for caching. It even uses it for its Java based container configuration.
Proxying means that your client code thinks it's talking to one bean, but a proxy is really doing the listening and responding.
This has been true since early distributed client/server computing models like CORBA. A client would interact with an interface type as if it existed in their memory space, but they were really talking to a proxy that would handle all the messy details around marshalling request data into a request, communicating over the network to the remote object running on a server, and unmarshalling the response back to the client.
Spring uses this model for remoting. It also forms the basis for its aspect oriented programming model. Your code thinks it's dealing with a particular interface; Spring can weave in advice before, after, or around that instance and perform cross cutting operations like logging, transaction management, etc. on your behalf.
Some frameworks rely on a mechanism called instrumentation, which in short means to build a proxy of a given compiled bytecode, adding some code to it in some places we judge useful. This would implement many kinds of tasks, between them for example, adding a kind of profiling to a spring bean, as this library claims to do.
The Spring engine returns heavily instrumented proxies of every managed bean it offers - this way, you can use Spring declarative transaction handling, for instance. You would write "naive" daos without an actual connection handling, and "naive" service classes using the daos without an actual transaction handling - the instrumented proxies will include the boilerplate code with the connection instantiation, commits, rollbacks...
I hope this is of any help

How to decouple a module which listens on a hibernate event from the entities themselves?

I have a layered web-application driven by spring-jpa-hibernate and I'm now trying to integrate elasticsearch (search engine).
What I Want to do is to capture all postInsert/postUpdate events and send those entities to elasticsearch so that it will reindex them.
The problem I'm facing is that my "dal-entities" project will have a runtime dependency on the "search-indexer" and the "search-indexer" will have a compile dependency on "dal-entities" since it needs to do different things for different entities.
I thought about having the "search-indexer" as part of the DAL (since it can be argued it does operations on the data) but even still it should be as part of the DAO section.
I think my question can be rephrased as: How can I have logic in a hibernate event listener which cannot be encapsulated solely in an entities project (since it's not its responsibility).
Update
The reason the dal-entities project is dependant on the indexer is that I need to configure the listener in the spring configuration file which is responsible for the jpa context (which obviousely resides in the dal-entities).
The dependency is not a compile time scope but a runtime scope (since at runtime the hibernate context will need that listener).
The answer is Interfaces.
Rather than depend on the various classes directly (in either direction), you can instead depend on Interfaces that surface the capabilities you need. This way, you are not directly dependent on the classes but instead depend on the interface, and you can have the interfaces required by the "dal-entities", for example, live in the same package as the dal-entities and the indexer simply implements that interface.
This doesn't fully remove the dependency, but it does give you a much less tight of a coupling and makes your application a bit more flexible.
If you are still worried about things being too tightly coupled or if you really don't want the two pieces to be circularly dependent at all, then I would suggest you re-think your application design. Asking another question here on SO with more details about some of your code and how it could be better structured would be likely to get some good advice on how to improve the design.
Hibernate supports PostUpdateEventListener and PostInsertEventListener.
Here is a good example that might suite your case
The main concept is being able to locate when your entity was changed and act after it as shown here.
public class ElasticSearchListener implements PostUpdateEventListener {
#Override
public void onPostUpdate(PostUpdateEvent event) {
if (event.getEntity() instanceof ElasticSearchEntity ) {
callSearchIndexerService(event.getEntity());
Or
InjectedClass.act(event.getEntity());
Or
callWebService(InjectedClassUtility.modifyData(event.getEntity()));
........
}
}
Edit
You might consider Injecting the class that you want to isolate from the project (that holds the logic) using spring.
Another option might be calling an outside web service that is not dependent on your code.
passing to it either the your original project object or one that is modified by a utility, to fit elasticsearch.

Factory class vs Spring DI

As per my understanding both Factory class and Spring DI follows the Dependency injection. I mean in both the cases external entity is used to push the dependency. Right?
My question is which one i should go for between factory classes and Spring DI when my intention is just to get the objects . Assume i don't want any other features like aop, dao support etc. Only purpose is to get the objects either from Factory class or Spring DI. Which one is preferable.
on some site read this statement
DI loosely coupled and less intrusive in comparison to Factory classes
But could not get how spring DI loosely coupled and less intrusive than factory classes?
in both the cases we have to insert some kind of get object code in our core program .
Spring DI promotes loosely coupled code because the Spring container injects your dependencies based on configuration. If you are injecting interface implementations, you don't have to change code to change which specific implementation gets injected, unless you consider your configuration code, which many do.
If you use a Factory to create configured objects that are used by the rest of your code, you are writing code to create the objects, configure them, etc. If you want to change what the factory returns, you have to change actual code, which some would argue is a more intrusive change.
Typically Spring is used to configure how the various layers of your application are wired together. X service takes such and such DAO implementations, for example. That's application level organization. Lets say you have a scenario where want to create a button for every row in a list -- in that case you could use a factory to create the buttons. This scenario is based on a runtime situation where the GUI has different elements that you couldn't configure up front (because its based on the data), so DI makes less sense here.
EDIT - based on your comment questions, I think the primary point here is that you have to consider is that Spring is also an Inversion of Control container. That means you don't program in which components in your application go where. Without IoC, you might do something like
MyServiceImpl extends MyService {
Dao1 = new Dao1Impl(); // you programmatically configure which components go in here
Dao2 = new Dao2Impl();
....
}
instead you do something like
MyServiceImpl extends MyService {
public Dao1; // you haven't specified which components, only interfaces
public Dao2;
....
}
In the second code sample, Spring (or whatever you use) will inject the appropriate DAO instances for you. You have moved control of which components to use to a higher level. So IoC and DI go hand and hand, IoC promotes loose coupling because in your component definitions (i.e. interfaces) you only specify behavior.
In other words, IoC and DI are not necessary for loose coupling; you can have loose coupling with a Factory too
MyServiceImpl extends MyService {
public dao1
public dao2;
MyServiceImpl(){
dao1 = DaoFactory.getDao1();
...
}
....
}
here your service still only depends on DAO definitions and you use the factory to get implementations. The caveat is that your service is now coupled to the factory. You can make it more loose by passing a Factory into your constructor if you want....
Also, dont forget that Spring provides other useful functionalities, like its transaction management. That's incredibly helpful, even though you said for your app you don't need it.
But could not get how spring DI loosely coupled and less intrusive
than factory classes? in both the cases we have to insert some kind of
get object code in our core program .
Spring makes it less intrusive because it uses reflection to automatically "inject/create" the dependencies. Thus your code does not need a reference to a the factory.
Spring is generally used for "Singleton-like" object creation. People generally use custom factories for transient throw away object creation (like request objects).
In fact often times you will make Spring create and inject your custom factories (ie factory of a factory).

spring and interfaces

I read all over the place about how Spring encourages you to use interfaces in your code. I don't see it. There is no notion of interface in your spring xml configuration. What part of Spring actually encourages you to use interfaces (other than the docs)?
The Dependency Inversion Principle explains this well. In particular, figure 4.
A. High level modules should not depend on low level modules. Both should depend upon abstractions.
B. Abstraction should not depend upon details. Details should depend upon abstractions.
Translating the examples from the link above into 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;
}
}
Now Copy supports more than just copying from a keyboard to a printer.
It is capable of copying from any Reader to any Writer without requiring any modifications 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" />
When you define an interface for your classes, it helps with dependency injection. Your Spring configuration files don't have anything about interfaces in them themselves -- you just put in the name of the class.
But if you want to inject another class that offers "equivalent" functionality, using an interface really helps.
For example, saying you've got a class that analyzes a website's content, and you're injecting it with Spring. If the classes you're injecting it into know what the actual class is, then in order to change it out you'll have to change a whole lot of code to use a different concrete class. But if you created an Analyzer interface, you could just as easily inject your original DefaultAnalyzer as you could a mocked up DummyAnalyzer or even another one that does essentially the same thing, like a PageByPageAnalyzer or anything else. In order to use one of those, you just have to change the classname you're injecting in your Spring config files, rather than go through your code changing classes around.
It took me about a project and a half before I really started to see the usefulness. Like most things (in enterprise languages) that end up being useful, it seems like a pointless addition of work at first, until your project starts to grow and then you discover how much time you saved by doing a little bit more work up front.
Most of the answers here are some form of "You can easily swap out implementations", but what I think they fail to answer is the why? part. To that I think the answer is almost definitively testability. Regardless of whether or not you use Spring or any other IOC framework, using Dependency Injection makes your code easier to test. In the case of say a writer rather than a PrinterWriter, you can Mock the Writer interface in a Unit test, and ensure that your code is calling it the way you expect it to. If you depend directly on the class implementation, your only option is to walk to the printer and check it, which isn't very automated. Furthermore, if you depend upon the result of a call to a class, not being able to Mock it may prevent you from being able to reach all code paths in your test, thus reducing their quality (potentially) Simply put, you should decouple Object graph creation from application logic. Doing so makes your code easier to test.
No one has mention yet that in many occasions won't be necessary to create an interface so that the implementing class can be switched quickly because simply there won't be more than one implementing class.
When interfaces are created without need, classes will be created by pairs (interface plus implementation), adding unnecessary boilerplate interfaces and creating potential dependency confusions because, on XML configuration files, components will be sometimes referenced by its interface and sometimes by its implementation, with no consequences at runtime but being incoherent regarding code conventions.
You may probably want to try using it for yourself to be better able to see this, it may not be clear from the docs how Spring encourages interface use.
Here are a couple of examples:
Say you're writing a class that needs to read from a resource (e.g., file) that may be referenced in several ways (e.g., in classpath, absolute file path, as a URL etc). You'd want to define a org.springframework.core.io.Resource (interface) property on your class. Then in your 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 is basically functioning as an extremely generic factory.
If you want to take advantage of Spring's AOP integration (for adding transaction interceptors for instance), you'll pretty much need to define interfaces. You define the interception points in your Spring configuration file, and Spring generates a proxy for you, based on your interface.
These are examples I personally have experience with. I'm sure there are much more out there.
it's easy to generate proxies from interfaces.
if you look at any spring app, you'll see service and persistence interfaces. making that the spring idiom certainly does encourage the use of interfaces. it doesn't get any more explicit than that.
Writing separate interfaces adds complexity and boilerplate code that's normally unnecessary. It also makes debugging harder because when you click a method call in your IDE, it shows the interface instead of the implementation. Unless you're swapping implementations at runtime, there's no need to go down that path.
Tools like Mockito make it very easy to test code using dependency injection without piling on interfaces.
Spring won't force you to use interfaces anywhere, it's just good practice. If you have a bean that has a some properties that are interfaces instead of concrete classes, then you can simply switch out some objects with mockups that implement the same interface, which is useful for certain test cases.
If you use for example the Hibernate support clases, you can define an interface for your DAO, then implement it separately; the advantage of having the interface is that you will be able to configure it using the Spring interceptors, which will allow you to simplify your code; you won't have to write any code cathing HibernateExceptions and closing the session in a finally segment, and you won't have to define any transactions programmatically either, you just configure all that stuff declaratively with Spring.
When you're writing quick and dirty apps, you can implement some simple DAO using JDBC or some simple framework which you won't end up using in the final version; you will be able to easily switch those components out if they implement some common interfaces.
If you don't use interfaces you risk an autowiring failure:
Sometime Spring creates a Proxy class for a Bean. This Proxy class is not a child class of the service implementation but it re-implements all of its interfaces.
Spring will try to autowire instances of this Bean, however this Proxy class is incompatible with the Bean class. So declaring a field with Bean class can lead to "unsafe field assignement" exceptions.
You cannot reasonably know when Spring is going to Proxy a service (nor should you), so to protect yourself against those surprises, your best move is to declare an interface and use this interface when declaring autowired fields.

Categories

Resources