0

I have a case where by I want all the classes that implement a particular interface to also inherit the annotations of the class, as well as the methods.

@Component
public interface ITask {
    @Scheduled(fixedRate = 5000)
    void execute();
}

public class TaskOne implements ITask {
    private static Logger LOGGER = LoggerFactory.getLogger(TaskOne.class);
    @Override
    public void execute() {
        LOGGER.info("Hello from task one");
    }
}

public class TaskTwo implements ITask {
    private static Logger LOGGER = LoggerFactory.getLogger(TaskTwo.class);
    @Override
    public void execute() {
        LOGGER.info("Hello from task two");
    }
}

So, I wanted both the tasks to be treated as a bean, as they are implementing an interface that is a bean. Also, I was hoping that the execute() methods of both the tasks would be scheduled at every 5 seconds. I have used the annotation @EnableScheduling with the main Application class containing the main() method.

Instead, I have to do this to make it execute in a periodic manner :

public interface ITask {
    void execute();
}

@Component
public class TaskOne implements ITask {
    private static Logger LOGGER = LoggerFactory.getLogger(TaskOne.class);
    @Override
    @Scheduled(fixedRate = 5000)
    public void execute() {
        LOGGER.info("Hello from task one");
    }
}

@Component
public class TaskTwo implements ITask {
    private static Logger LOGGER = LoggerFactory.getLogger(TaskTwo.class);
    @Override
    @Scheduled(fixedRate = 5000)
    public void execute() {
        LOGGER.info("Hello from task two");
    }
}

I don't want want to annotatae every task with this @Component annotation, and the @Scheduled annotation for every execute method. I was hoping to provide some default value for @Scheduled, and that the @Component annotation can be taken care of by implementing a certain interface.

Is it possible in Java ?

OneMoreError
  • 7,518
  • 20
  • 73
  • 112

1 Answers1

2

This is not possible is Java.

You'll have to annotate different classes separately.

But if this is a custom annotation being talked about, you could mark the annotation with @Inherited and put it on a base class, and have all your other classes extend the base class.

Anyway, you cannot annotate @Component or @Scheduled with @Inherited, so in this use case this solution would not work.

Why is this not allowed(from another answer here):

I'd say the reason is that otherwise a multiple-inheritance problem would occur.

Example:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Inherited
public @interface Baz { String value(); }

public interface Foo{
    @Baz("baz") void doStuff();
}

public interface Bar{
    @Baz("phleem") void doStuff();
}

public class Flipp{
    @Baz("flopp") public void doStuff(){}
}

public class MyClass extends Flipp implements Foo, Bar{}

If I do this:

MyClass.class.getMethod("doStuff").getAnnotation(Baz.class).value()

what's the result going to be? 'baz', 'phleem' or 'flopp'?

Community
  • 1
  • 1
Sandeep Kaul
  • 2,957
  • 2
  • 20
  • 36
  • I understand what you're saying. So, is there no other design pattern that is being followed to solve such code designs ? – OneMoreError Dec 17 '15 at 07:33
  • Not that I am aware of. I looked up for a very similar thing recently, and I didn't find anything around this except for the `@Inherited` way – Sandeep Kaul Dec 17 '15 at 07:35
  • I know it's pretty late for an answer, but I stumbled upon this question while searching an clue for this exact problem Theoretically you can implement the interface and make one handler class. In this handler class you once define the `@Scheduled` and let Spring inject you all the `ITask`s via `@Autowired List tasks`. And in the handler class in the scheduled method you just iteratively call the `execute()` Method You got just one place to define the fixedRate and easily implement the interface while Spring will do the rest. Hope this helps others – oruckdeschel Aug 04 '17 at 21:17