What's the Difference Between @Component, @Repository & @Service Annotations in Spring

What's the difference between how @Component and @Repository / @Service annotations are processed?

I've been using @Component without troubles.

The only thing (although not-so-intelligent one) that comes to my mind as possibility is that your @Component might not be the spring one. Tapestry, for example, has an annotation named the same way. Other frameworks may also have it. So check your imports.

When to use service or component in spring?

In order to "configure" Spring so it can provide you with the instances of the classes you need, you are supposed to tell Spring what objects are involved and how they are built. To do this you can use an xml configuration file or through annotations

In case you take the annotation approach (IMHO a much better and simpler one) you can use @Component to annotate the class. This is like telling Spring: "Hey! I want you to know that you may need an instance of this class. Maybe because I request it, maybe because something I requested needs it". So annotating a class with @Component just let Spring know that it exists

There are other annotations that do the same:

  • @Controller (and @RestController)
  • @Service
  • @Repository

They all inform Spring that the class is involved in the DI context. But they also have semantic meaning:

  • @Controller = @Component belonging to Presentation Layer
  • @Service = @Component belonging to Service/Use Case Layer
  • @Repository = @Component belonging to Persistence Layer

You can find more info in this question

Should a service be able to call the other services?

I don't see any problem with that. If any of your services requires to do some actions that are already performed by other you surely want to avoid code duplication. As long as you respect the architecture layers dependency (never going up) you'll be fine.

About this you can check this article about Clean Architecture

When should I use @Component instead of @Service?

Keep in mind that these are Spring stereotypes, and should be applied as stereotypes or assumptions around one's code are usually applied.

  • If your component is a generic component, not really living at the service layer, or is accessible but could hold state, then use @Component.
  • If your component is a specific service, living at the service layer, or is accessible and does not inherently hold state, use @Service.

Spring sees both of these ultimately as @Components.

For the spring autodetection, what's the difference between component and service?

The basic difference between both annotations is that @Service is a specialization of @Component.

See also spring documentation for @Service:

Indicates that an annotated class is a "Service" (e.g. a business
service facade).

This annotation serves as a specialization of @Component, allowing for
implementation classes to be autodetected through classpath scanning.

A specialization of component is also a @Repository and a @Controller

Further information can be found e.g. here.

what is the difference between @Bean annotation and @Component annotation at Spring?

Component

@Component also for @Service and @Repository are used to auto-detect and auto-configure beans using classpath scanning.

As long as these classes are in under our base package or Spring is aware of another package to scan, a new bean will be created for each of these classes

Bean and Component are mapped as one to one i.e one bean per Class.

These annotations (@Component, @Service, @Repository) are Class level annotations.

Example:

Lets Say we have a UserService Class which contains all methods for User Operation.

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

@Override
public User findByUsername( String username ) throws UsernameNotFoundException {
User u = userRepository.findByUsername( username );
return u;
}

public List<User> findAll() throws AccessDeniedException {
List<User> result = userRepository.findAll();
return result;
}
}

Spring will create a Bean for UserService and we can use this at multiple location/classes.

@Bean

@Bean is used to declare a single bean, rather than letting Spring do it automatically as in case of Component.

It decouples the declaration of the bean from the class definition, and lets you create and configure beans exactly how you choose.

@Bean are used at method level and can be configured as required

eg:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


@Bean
public SpringTemplateEngine springTemplateEngine()
{
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver());
return templateEngine;
}

@Bean
public SpringResourceTemplateResolver htmlTemplateResolver()
{
SpringResourceTemplateResolver emailTemplateResolver = new SpringResourceTemplateResolver();
emailTemplateResolver.setPrefix("classpath:/static/template/");
emailTemplateResolver.setSuffix(".html");
emailTemplateResolver.setTemplateMode("HTML");
emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
return emailTemplateResolver;
}


...

Read more about Stereotype Annotations here.

Difference between Component-Scan and @Component ?

Using the annotation @ComponentScan , you can tell Spring where do your Spring-managed components lie. These Spring-Managed components could be annotated with @Repository,@Service, @Controller and ofcourse @Component.

For example - Lets say your spring-managed components lie inside 2 packages com.example.test1 and com.example.test2. Then your componentScan would be something like this

                @ComponentScan(basePackages="com.example.test1","com.example.test2")

OfCourse the annotation ComponentScan has a lot of other elements.

You can read more about them here -
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html.

On the other hand, @Component is a generic annotation for any Spring-Managed component. For example - If you create a class called Testing inside the package com.example.test1 and annotate with Spring @Component.

             @Component    
Class Testing
{

public Testing()
{
}

public void doSomething()
{
System.out.println("do something");
}

}

Following the above example, During Component Scan it will be picked up and added to the application context.

Hope this makes things clear :)



Related Topics



Leave a reply



Submit