Есть код:
String[] tasks = {"", "main.tasks.GetJSPFTask"};
....
Class<AbstractTask> cat;
AbstractTask at = null;
cat = (Class<AbstractTask>)Class.forName(tasks[taskId]);
at = cat.getConstructor().newInstance();
....
AbstractTask - простой интерфейс с одним статическим методом
public interface AbstractTask {
public boolean processTask(UserEnv ue,
HttpServletRequest req,
HttpServletResponse res);
}
Вся эта лабуда позволяет через один сервлет получать страницы (пока
только страницы), JSON кучки и проч. для расширяемости задумана
фабрика (она и приведена), которая в зависимости от параметров
запроса и типа запроса загружает нужный класс. Вопрос в следующем,
нет ли косяков в сем подходе - сомнения возникают по поводу
быстродействия и того что происходит с jvm если постоянно подгружать
один и тотже класс, в общем не ляжет ли сервер при таких извратах?
Насколько я понимаю, планируется создание нового stateless объекта для обработки каждого запроса - и это главная проблема, а использование reflection само по себе - мелочь. Остальное - велосипед, runtime dispatch запроса к соответствующему объекту и так везде используется.
+1. Class.forName вроде как должен один и тот же класс возвращать (если нет игры с лоадерами). А вот каждый раз новый объект класса создавать - это может оказаться дорого. Может, можно как-то синглтончик замутить?
Собстно и думаю сделать синглтон фабрики, тогда можно будет и массив id-класс сваять и погружать его один раз, возник вопрос нет ли подводных камней с многопоточностью?
Саму getInstance не надо делать synchronized. А вот доступ к данным внутри самого объекта - придется. Но аккуратно, чтоб не наделалть всяких локов. И что не тормозило все (а то ведь можно так насинхронизовать, чт обыстрее окажется создавать по объекту на обработчик).
Я прально понимаю, что так достаточно ?
static synchronized public AbstractTask getTaskInstance(int taskId) {
//lock()
if (m_ti == null) {
m_ti = new TaskInstancer();
}
//unlock()
AbstractTask at = null;
try {
//lock()
at = m_constrs.get(taskId).newInstance();
//unlock()
}
catch (Exception e) {
}
return at;
}
где
private static HashMap<Integer, Constructor<AbstractTask>> m_constrs;
или последний лок не нужен?