Insights from Stackoverflow: Most voted for Spring 4 questions
What are the most voted for Spring 4 question asked and answered on Stackoverflow? Here are the top five questions and answers.
- What’s the difference between @Component, @Controller, @Repository & @Service annotations in Spring, can they be used interchangeable or do they have specific functionality?
- Where does the @Transaction annotation belong? The DAO class, the service that calls the DAO or both?
- What is the difference between @Inject and @Autowired? Which one to use under what condition?
- Which annotation should I use @Resource or @Autowired? What is the difference?
- What is the Spring Framework for?
What’s the difference between @Component, @Controller, @Repository & @Service annotations in Spring, can they be used interchangeable or do they have specific functionality?
These stereotypes are intended to mark different layers in a multi-tier application. Components within the business, presentation and persistence layers are annotated respectively by @Service, @Component and @Repository as follows:
- Data access components are annotated @Repository
- service components @Service
- controller components are annotated @Controller
- any other component is annotated @Component.
All these annotations are themselves annotated with @Component. So the question is: Can we use @Component for all auto scanned classes? Yes and No!
All classes marked with this annotation will be auto scanned, however it would not be considered good practice as these annotations are designed to help the developer clearly communicated the intent of the component.
There is one exception to the technical interchangeability of these annotations. The @Repository marker confers special behaviour to all beans it annotates. The PersistenceExceptionTranslationPostProcessor automatically applies persistence exception translation to any bean marked with @Repository.
Consider the following paragraph from the Spring framework reference manual.
The postprocessor automatically looks for all exception translators (implementations of the PersistenceExceptionTranslator interface) and advises all beans marked with the
@Repository
annotation so that the discovered translators can intercept and apply the appropriate translation on the thrown exceptions.
A further consideration is that, in a future version of the Spring framework, the use of these annotation may convey special functionality relevant to their respective tier and by using these annotations appropriately you ensure that your application will benefit from such functionality with no or minimal refactoring.
The original question and answers can be viewed on the Stackoverflow website. Thank you to the following posters who answers form part of this article: akash746, nijogeorgep and Colin McCree who asked the original question.
Where does the @Transaction annotation belong? The DAO class, the service that calls the DAO or both?
Answers are divided into two camps: those who favour the annotation of classes at the service layer and those whose perfect to annotation the DAO.
The service layer
Traditional Spring architecture suggests that transactional semantics are located at the service level. The atomicity of the operation should inform our decision. The transaction annotation should be placed around all operations that are inseparable. Consider the classic example of a money transfer. It consists of the following calls:
- Credit the sends account
- Debit the receivers account
Both transactions must succeed or fail, so the transaction must surround both calls one and two.
If the service layer must call different methods on DAO in the data access layer in order to perform a complete operation and one of those calls fails while other success it may result in inconsistent database state. Therefore annotating around the calls made at the service layer will protect the atomicity of the operation.
For additional certainty, you may wish to annotate the debit and credit calls in the Data Access Layer by adding @Transactional(propagation = Propagation.MANDATORY). This will ensure that a transaction has been started in the caller and if no active transaction exists an exception will be thrown.
Annotating the service layer may results in longer lasting transactions than direct annotations on the DAO methods. The choice you make will depend on the level transaction isolation that the business logic requires.
DAO
There is an emerging trend towards domain-driven design. Spring Roo is a nice example of this trend.
The idea is to make the domain object a lot richer than they are in a traditional Spring architectures, usually they are anaemic, and in particular to put transaction and persistence semantics on the domain objects themselves.
In use cases where all that is needed are simple CRUD operations, the web controllers operate directly on the domain object (functioning as entities in this context), and there is no service tier.
In cases where there’s some kind of coordination needed between domain objects, you can have a service bean handle that, with @Transaction as per tradition. You can set the transaction propagation on the domain objects to something like REQUIRED so that the domain objects use any existing transactions, such as transactions that were started at the service bean.
The original question and answers can be viewed on the Stackoverflow website. Thank you to the following posters who answers form part of this article: Willie Wheeler, Michael Wiles, mnp, tweekran, djt and Thomas Einwaller who asked the original question.
What is the difference between @Inject and @Autowired? Which one to use under what condition?
The short answer: There is no different and can be used interchangeably.
In more detail the @Inject annotation is part of Java EE 7’s Context and Dependency Injection framework (JSR 346 also see JSR 365 for Java 2.0) while @Autowired is the Spring Frameworks own implementation (see Java doc).
The original question and answers can be viewed on the Stackoverflow website. Thank you to the following posters who answers form part of this article: pap and Rachel who asked the original question.
Which annotation should I use @Resource or @Autowired? What is the difference?
Both the @Autowired (or @Inject) and @Resource annotations function equally. But there is a conceptual difference:
- the @Resource should be used to get a known resource by name. The name is extracted from the annotated setter or field, or is taken from the name the annotation’s name parameter.
- the @Inject or @Autowired annotations attempt to inject a suitable component by type.
Essentially these are two distinct concepts. Disappointingly Spring’s Implementation of the @Resource annotation has a built-in fallback, which triggers when resolution by-name fails. It falls back to the resolution by-type as used by the @Autowired annotation. Although this fallback is convenient, it could cause confusion, as people are unaware of the conceptual difference and would tend to use @Resource for type-based injections.
The manner is which dependencies are selected is specific to the annotation. Here is how each annotation resolves injection:
@Autowired and @Inject
- Matches by Type
- Restricts by Qualifiers
- Matches by Name
@Resource
- Matches by Name
- Matches by Type
- Restricts by Qualifiers (ignored if match is found by name)
This quote from the Spring Reference Manual suggests the use of @Resource in favour of @Autowired where inject by name is preferred.
If you intend to express annotation-driven injection by name, do not primarily use
@Autowired
, even if is technically capable of referring to a bean name through@Qualifier
values. Instead, use the JSR-250@Resource
annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through
@Autowired
, because type matching is not properly applicable to them. Use@Resource
for such beans, referring to the specific collection or map bean by unique name.
@Autowired
applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast,@Resource
is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.
The original question and answers can be viewed on the Stackoverflow website. Thank you to the following posters who answers form part of this article: kartik, Stephan, Ichthyo and mlo55 who asked the original question.
What is the Spring Framework for?
The Spring Framework can be describe is three ways:
- Spring is a framework for dependency injection: a design pattern that allows the developer to build very decoupled systems by injecting dependencies into classes.
- It elegantly wraps Java libraries and makes then much easier to use in your application.
- Included in the framework are implementations of commonly used patterns such as REST and MVC web framework which are predominately use by in web applications.
The original question and answers can be viewed on the Stackoverflow website. Thank you to the following posters who answers form part of this article: karstensrage and maksim who asked the original question.
I hope you have found this insight into the most popular questions asked on stackoverflow interesting. If you have any feedback please leave a comment. The original posting of this article can be found here: Insights from Stackoverflow: Most voted Spring 4 questions.
If you are interested in design pattern you might be interested in my new book: Professional Java EE Design Patterns. It is the perfect companion for anyone who wants to work more effectively with Java EE, and the only resource that covers both the theory and application of design patterns in solving real-world problems.
Reference: | Insights from Stackoverflow: Most voted for Spring 4 questions from our JCG partner Alex Theedom at the alex.theedom blog. |