Jeremythuff
Jeremythuff

Reputation: 1548

Spring Custom Annotations

I am not sure if it is possible to easily do what I am wanting to do. I have the following controller which works as both a rest and websocket controller:

@RestController
@RequestMapping("rest/user")
@MessageMapping("/user")
public class UserController {

    @Autowired
    private UserRepo userRepo;

    @RequestMapping("/list")
    @MessageMapping("/list")
    @SendTo("/channel/user")
    public apiResImpl list() {      
        Iterable<UserImpl> users = userRepo.findAll();  
        return users != null ? new apiResImpl("success", users) :  new apiResImpl("fail");
    }

 ...

I would like to wrap several of these annotations up in a two custom annotations @ApiController and @ApiMapping

Something like this:

@ApiController("/user")
public class UserController {

    @Autowired
    private UserRepo userRepo;

     @ApiMapping("/list")
     public apiResImpl list() {     
         Iterable<UserImpl> users = userRepo.findAll(); 
         return users != null ? new apiResImpl("success", users) :  new apiResImpl("fail");
     }

 ...

The issue I am having is being able to pass values into the custom annotation that are internally handed to the spring annotations. What would this @interface look like? Any examples?

Thanks!

Upvotes: 1

Views: 2130

Answers (2)

Rahogata
Rahogata

Reputation: 496

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@RequestMapping // meta-annotated RequestMapping 
@MessageMapping // meta-annotated MessageMapping
public @interface ApiController {

     @AliasFor(annotation = RequestMapping.class, attribute = "value") // -> alias for RequestMapping value attribute
     String[] value() default {};

     @AliasFor(annotation = MessageMapping.class, attribute = "value") // -> alias for MessageMapping value attribute
     String[] mvalue() default{};   
}


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@RequestMapping
@MessageMapping
public @interface ApiMapping {

    @AliasFor(annotation = RequestMapping.class, attribute = "value")
    String[] value() default {};

    @AliasFor(annotation = MessageMapping.class, attribute = "value")
    String[] mvalue() default {};

    @AliasFor(annotation = RequestMapping.class, attribute = "method")
    RequestMethod[] method() default {};
}

Referring the below link I have come up with this solution, using this technique we can give an alias to the attribute of meta-annotated annotation i.e., (here RequestMapping, MessageMapping).

One disadvantage of AliasFor is, it is non repeatable annotation.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#_core_container_improvements_2

Upvotes: 3

Rohith K
Rohith K

Reputation: 1492

         @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@RestController
@RequestMapping(value="/rest/*")
@MessageMapping
public @interface ApiController {
    String value() default "";

}

Upvotes: 0

Related Questions