Implementing an interface is tight coupling? - spring

It says here that
I would not recommend to use InitializingBean and DisposableBean
interface, because it will tight coupled your code to Spring
Does it make sense? I thought this would be just the opposite to tight-coupling.

Here the author means that if you let your application classes implement InitializingBean and DisposableBean interfaces (that are spring specific interfaces), then you are coupling your code with spring.
In future if spring renames these interfaces (unlikely though), or you stop using spring you will have to update your class code.
Instead if you use init-method and destroy-method attributes in your bean config, your class is independent of spring, i.e. there is no depedency of your class on spring specific classes.
Hope it helps.

I think the idea here is to not create any dependency on your code to spring annotations, see
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
When you explicitly declare this kind of dependency, you're coupling your code to spring jars.
In this other example - http://www.mkyong.com/spring/spring-init-method-and-destroy-method-example/ - it shows how you could use convention methods defined in the XML. No spring imports.

Related

What class implements the spring framework Autowired

I downloaded the spring-framework project, because I want to see how #Autowired is implemented.
So, I got to this file, which is an interface.
But when I want in Intellij to go to its implementation, no implementations are found.
So is this interface not implemented?
Then where is the code for #Autowired?
Well, this is not an interface it is actually an annotation.
In java #inteface is used to create an annotation.
Once the annotation is created, you can use that annotation on fields, classes, methods (based on what is specified in #Target of the annotation definition.
Spring does package scanning and finds all the things which are using a particular annotation and does the required processing.
Use this article to undestand more in How an annotation is created, used and the how the annotation processor finds and processes the annotation.
#Autowired doesn't really have much code, so to speak. It's just an annotation which is a Java type of interface that provides instructions to other parts of the codebase.
#Autowired is only an annotation or you can say a "marker". Spring use reflection to identify annotation and do something about that annotated thing. For example with #Autowired, when spring found it, spring will inject the annotated property with eligible bean.

How #Aspect with #Component annotation works under the hood

I've been looking for an answer for a while, but no luck so far, thus I'm coming here for some words of wisdom.
I've created an aspect using #Aspect annotation, because I need to #Autowire some singleton dependencies I've decided to annotate this aspect class with #Component and let the Spring to do the magic. It works, however ...
I'm fairly familiar with AOP concept, what's weaving and different flavors of it (cglib vs aspectj) but it's not fully intuitive to me how it works under the hood.
#Component means a given class will be a singleton within a given context, #Aspect means that the content of an aspect class will be somehow weaved into the target class during runtime/compilation - and this target class is not a singleton but prototype for instance. So what I'm ending up with at the end?
Spring AOP does not do compile-time-weaving and does not modify the code of the advised target. Instead it works with proxies that are weaved around the joinpoints. That is why Spring AOP aspects and be used as (singleton) components, have their fields autowired, etc., like any other Spring Proxy.
It is also the reason why Spring AOP aspects only work for public method executions, not field accesses and the like.
The documentation is quite well written and goes into as much (or as little) detail as one might like:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
The book AspectJ in Action's section 2.5 is on the internal working of the weaving step, it is only 2 page but gets the point across well.
Luckily the section is available here.
This is for posterity.

Spring annotations for service layer and db layer

Is this good practice to mark service class with annotation #service and #repository , since I am doing most of my DB operations in my service class. Does spring treats them a singleton class or prototype?
It makes easier for Spring to target pointcuts with more specific annotations. So, you should code DB operations in DAO layer and annotate it with #Repository as it causes exceptions to be wrapped up as DataAccessExceptions. Also, coding related stuff in it's own layer give rise to code modularity and reuse.
Moreover using the specialized annotations help to clearly demarcate application layers, in a standard 3 tier application.
Does spring treats them a singleton class or prototype?
By default all beans are of Singleton scope in Spring. To make it serve as prototype you have to change the scope of bean.

Why interface is injected instead of class in Spring MVC

I am reading the Spring Hibernate CRUD tutorial from this url
http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/
Please can anyone tell me why in ContactController.java, ContactService interface is autowired instead of the class ContactServiceImpl.
Similarly in ContactServiceImpl ContactDAO interface is injected. Shouldn't we supposed to inject class instead of an interface?
When your code is dependent on interface and its implementation is injected by Spring, your code becomes decoupled with the implementation. This has an advantage that now you can swap in a different implementation without having to change the code that makes use of interface.
Spring is smart. It will find the implementation of the interface and inject it appropriately (or a proxy thereof.)
You should be programming to interfaces, not implementations.

Combine two maven based projects on two frameworks

I have two maven projects say MvnSpring and MvnGuice.MvnSpring is working on spring and hibernate frame works.
And MvnGuice is working on google guice and mybatis. I need to combine both the features together.
Both are following singleton pattern. I need to get some class of MvnSpring in MvnGuice while coding. So that I created a jar of MvnSpring and put it in .m2 repository and give the dependacy details in MvnGuice. Now I can import classes of MvnSpring in MvnGuice classes.MvnSpring uses spring dependency injection and MvnGuice uses guice dependency injection for object creation. Now in MvnSpring flow is MSserviceImpl(implements MSservice) > MSdaoImpl(implements MSdao). Now I need to call MSService class from MvnGuice. Then at run time it shows error like MSService class is null. Then I made a guice dependency injection for MSService class in MvnGuice. Now the control reaches MSserviceImpl but now MSdao is null at here. Is it possible to start MvnSpring along with MvnGuice. I hope then I can solve the issue.
While Spring and Guice are targeted at the same problem, IoC, they take very different approaches to solve it. They differ both in functionality and in how they are configured, where Spring has bean definitions and Guice uses bindings.
Fortunately they do have common grounds in that they both support JSR-330, a standards specification that defines a set of annotations. This enables you to write your singletons and describe the injections that they need without depending on either Spring or Guice.
This way you can share your singletons between projects irregardless of the framework you use in a particular project. I would not recommend using both Guice and Spring in the same project, except if there's a clearly defined separation between them. For instance you might use Guice for a module that is used by Spring code via a defined API that hides the fact that it internally is based on Guice.
There was already mentioned JSR-330.
For some cases it can be not enough, e.g., you have code:
final String className = config.getProperty(«serviceImpl»);
// Class.forName(name) and check required interface for type safety
final Class<? extends Service> serviceClass = Reflection.classForName(className, Service.class);
final Service service = injector.getInstance(serviceClass);
In different DI environments you are supposed to support both com.guice.inject.Injector.getInstance() and org.springframework.context.ApplicationContext.getBean() implementations.
There is the draft solution sdif4j Simple Dependency Injection Facade.
The idea of this project is to encapsulate different DI frameworks logic with own abstraction to extend default JSR-330 possibilities. Note, there is no public releases yet, but you can find ideas how to solve your problem or make an internal release in a fork.
The general issue, is that your both MvnSpring and MvnGuice projects are supposed to be based on JSR-330 (instead of guice/spring annotations) and org.sdif4j:sdif4j-api (or your own abstraction; only if Injector functionality is required). It is recommended to make guice and spring dependencies optional (to compile but not export) to allow the library clients to choose the DI themselves.
In your MvnCompineGuiceAndSpring you just declare sdif4j-guice or sdif4j-spring dependency (it is similar to slf4j usage) and configure your DI environment. You can find different examples in testing subproject.
Some more notes:
Spring default scope is singleton, Guice - prototype (Spring terminology). So, if you want a prototype bean, you can use:
#org.springframework.context.annotation.Scope("prototype")
#javax.inject.Named
public class TestPrototype {
}
The Spring #Scope annotation should be ignored by guice even if spring does not present in your classpath.
Also you have to declare all your Singleton beans with #javax.inject.Named and #javax.inject.Singleton annotation to support both Spring and Guice, like this:
#javax.inject.Named
#javax.inject.Singleton
public class TestSingleton implements ITestSingleton {
public TestSingleton() {
}
}
As with #Scope annotation, you can use #ImplementedBy(#ProvidedBy) guice annotations on your code (when feasible; be careful with it, in general it is not a good practice), that should be also ignored in Spring DI (in both cases if Spring exists in classpath or not).
Hope, that's clear.

Resources