The title may be a bit misleading but I am trying to find the best solution in connecting database entries to spring beans. I hope that the example that follows will clarify things.
For starters, I have a Task
entity.
@Entity
@Table( name = "tasks")
class Task {
}
I also have a TaskExecutor
interface that has only one method, execute Task.
public interface TaskExecutor {
void executeTask(Task t);
}
Now, I currently have 3 implementations of the TaskExecutor
interface.
@Service("taskExecutorOne")
class TaskExecutorOne implements TaskExecutor {
}
@Service("taskExecutorTwo")
class TaskExecutorTwo implements TaskExecutor{
}
@Service("taskExecutorThree")
class TaskExecutorThree implements TaskExecutor{
}
Now, every task should be executed by one of these three task executors. What I am having trouble with, is determining the best solution for creating the connection between the task database entries and the available executor services.
1. One way of doing it is to create an ExecutorType
enum with three values:
enum ExecutorType {
EXECUTOR_ONE,
EXECUTOR_TWO,
EXECUTOR_THREE
};
We can add a column in the tasks table that will contain the value of the enum for the particular task. This way, when we need to get the executor for the task, we could do something like this:
@Service
class TaskRegisterService {
@Autowired
@Qualifier("taskExecutorOne")
private TaskExecutor taskExecutorOne;
@Autowired
@Qualifier("taskExecutorOne")
private TaskExecutor taskExecutorOne;
@Autowired
@Qualifier("taskExecutorOne")
TaskExecutor taskExecutorOne;
public TaskExecutor getExecutorForTask(Task t) {
if(t.executorType == ExecutorType.EXECUTOR_ONE)
return taskExecutorOne;
else if(t.executorType == ExecutorType.EXECUTOR_TWO)
return taskExecutorTwo;
else if(t.executorType == ExecutorType.EXECUTOR_THREE)
return taskExecutorThree;
}
}
I don't like this solution because the creation of a new service would require adding a new entry in the enum and a new if
part inside the getExecutorForTask
method.
2. Another way of doing is by storing the bean name inside the tasks
table. In that case, the getExecutorForTask
would look like this:
@Service
class TaskRegisterService {
@Autowired
private ApplicationContext applicationContex;
public TaskExecutor getExecutorForTask(Task t) {
return (TaskExecutor) applicationContex.getBean(t.getBeanName());
}
}
This way, I will be able to add new executors without adding any additional code inside the getExecutorForTask
method but I will have to store bean names inside the database.
Is there any better way of solving the problem that I just described? If not, which of the approaches that I described seems better? My goal is to be able to easily add new Executors, with modfying as small amount of code as possible.