2

I want to understand which class in Spring framework distinguishes functionality of @Controller, @Service, @Repository annotations. Upon comparing source code of these three annotations understood that only class name is different.

Say, how does spring understand StudentController is only Controller and not Service or Repository?

@Controller
public class StudentController {
}

@Service
public class StudentService {
}

@Repository
public class StudentRepository {
} 

Source codes of spring stereotype annotations

Controller.class

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Service.class

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Repository.class

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Since source code is same for these annotations, their functionality is distinguished (as each one has different use cases) in framework classes somewhere otherwise framework allows users to use these annotations interchangeable.

1 Answers1

0

I want to understand which class in Spring framework distinguishes functionality of @Controller, @Service, @Repository annotations. Upon comparing source code of these three annotations understood that only class name is different.

The usage is nuanced and often your answers are going to be found by searching for references (e.g. in Eclipse.

For example, @Controller is referenced specifically in RequestMappingHandlerMapping.

Say, how does spring understand StudentController is only Controller and not Service or Repository?

The plumbing knows what to do with specific annotations. To answer your question directly: it knows StudentController is an @Controller because you have annotated it thus. It is not annotated as @Repository, so it's not a repository.

@Controller itself has a RetentionType.RUNTIME so that Spring can inspect / check for it using reflection.

Finally, note that @Controller (and the other stereotypes you mentioned) are themselves @Components. So a type marked as @Controller is implicitly also a @Component.

Not a JD
  • 1,864
  • 6
  • 14
  • 1
    **RequestMappingHandlerMapping.java** is checking if class is annotated with **@Controller** or not in below method. ```@Override protected boolean isHandler(Class> beanType) { return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class)); }```. Thanks for it. Similarly, somewhere is checked for functionality of @Repository, @Service as well. Reflection doesn't understand unless one is defined how it should work at framework level. – Rambabu Kokkiligadda Apr 02 '19 at 04:21