Давай поговорим об этом сначала
Недавно я изучаю домашнее промежуточное программное обеспечение для базы данных MySQL с открытым исходным кодом. После того, как он вытащил свою последнюю версию кода в Eclipse, запустите его и выполнив различные тесты и отслеживание кода. Когда я хочу закрыть его после использования, я вытаскиваю его класс Stop и хочу запустить его. Я обнаружил, что в этом классе были написаны только следующие строки кода, поэтому я чувствовал, что мне очень больно в одно мгновение.
public static void main (string [] args) {System.out.println (new Date () + ", выключение сервера!"); }Когда это промежуточное программное обеспечение запускается и запускается, прослушивание включено, много потоков запускаются, и есть много подключений к сокетам. Но нет элегантного способа выключить его. Поэтому в отчаянии я мог пойти только в маленькую красную точку затмения и насильно остановил виртуальную машину.
Если это программное обеспечение с хорошей архитектурой, четкое и модульное программное обеспечение, особенно серверное программное обеспечение, очень важно иметь набор механизмов управления жизненным циклом. Мало того, что он может управлять жизненным циклом каждого модуля, он также может быть более элегантным при запуске и остановке всего программного обеспечения без отсутствия ресурсов.
Простая реализация механизма жизненного цикла
Жизненное состояние
Состояние жизненного цикла модуля обычно имеет следующее:
Newborn-> Инициализация-> Инициализация завершена-> Инициализация-> Инициализация завершена-> Инициализация-> papusing-> papusing-> reffering-> reffering-> destrecting-> destressing-> destrying. Если преобразование между любыми состояниями не удастся, оно войдет в другое состояние: сбой.
Для этого вы можете использовать класс перечисления для перечисления этих состояний, как показано ниже:
Public Enum LifeCyclestate {новый, // Newsen инициализируется, инициализируется, // инициализировать запуск, запустить, // начать приостановить, приостановить, // паузу возобновить, возобновить, // восстановить уничтожение, уничтожение, // уничтожение не удалось; // не удалось}интерфейс
Различные поведенческие нормы в жизненном цикле также требуют определения интерфейса, как показано ниже:
публичный интерфейс ilifecycle { / ** * инициализировать * * @Throws LifeCycleException * / public void init () бросает LifeCycleException; / ** * start * * @Throws LifeCycleException */ public void start () бросает LifeCycleException; / ** * PAUSE * * @Throws LifeCycleException */ public void suspend () бросает LifeCycleException; / ** * восстановить * * @Throws LifeCycleException */ public void resume () бросает LifeCycleException; / ** * Уничтожить * * @Throws LifeCycleException */ public void destress () бросает LifeCycleException; / ** * Добавить слушатель жизненного цикла * * @param слушатель */ public void addlifecyclelistener (ilifecyclelistener слушатель); / ** * Удалить слушатель жизненного цикла * * * @param слушатель */ public void removelifecyclelistener (ilifecyclelistener слушатель);}Когда происходит переход состояния жизненного цикла, слушателей, которые заинтересованы в определенном типе событий, могут потребоваться запустить, поэтому Ilifecycle также определяет два метода для добавления и удаления слушателей. Это: public void addlifecyclelistener (слушатель ilifecyclelistener); и public void removelifecyclelistener (слушатель ilifecyclelistener);
Слушатель также определяет свои поведенческие нормы интерфейсом, как показано ниже:
Общедоступный интерфейс ilifecyclelistener { / *** Хранение событий жизненного цикла*** @param события событий жизненного цикла* / public void LifeCycleevent (событие LifeCycleevent);}События жизненного цикла представлены LifeCycycleevent, как показано ниже:
Public Final Class LifeCycleevent {Private LifeCyclestate State; public LifeCycleEvent (состояние жизненного цикла) {this.state = state; } / ** * @return the State * / public LifeCyclestate getState () {return State; }}Реализация скелета
С интерфейсом ilifecycle любой класс, который реализует этот интерфейс, будет использоваться в качестве объекта управления жизненным циклом. Этот класс может быть службой прослушивания сокетов, или он может представлять конкретный модуль и т. Д. Так нам просто нужно реализовать Ilifecycle? Можно сказать, что, учитывая, что каждый объект управления жизненным циклом будет иметь некоторое общее поведение на разных этапах жизненного цикла, например:
Установка вашего собственного состояния жизненного цикла, чтобы проверить, соответствует ли переход государства логике, чтобы уведомить слушателя о том, что состояние жизненного цикла изменилось. Следовательно, важно обеспечить абстрактный классовый абстрактный резист как скелетный реализацию Ilifecycle, что позволяет избежать большого количества дубликата кода и делает архитектуру более четкой. Этот абстрактный класс будет реализовать все методы интерфейса, определенные в Ilifecycle, и добавят соответствующие абстрактные методы для реализации подкласса. AbstractLifeCycle может быть реализован так:
Общедоступный абстрактный класс AbstractLifeCycle реализует ilifecycle {private list <iLifeCycLeListener> слушатели = новый CopeOnWritearRayList <IlifeCycleliStener> (); / *** Состояние представляет текущее состояние жизненного цикла*/ частное состояние жизни / * * @see ilifecycle#init () */ @override public final Synchronized void init () Throws LifeCycleException {if (state! = LifeCyclestate.new) {return; } setStateAndfireevent (LifeCyclestate.initialize); try {init0 (); } catch (throwable t) {setStateAndfireevent (LifeCyclestate.failed); if (t ancessionof LifeCycleException) {Throw (LifeCycleException) t; } else {бросить новое LifeCycleException (formatString ("Не удалось инициализировать {0}, ошибка msg: {1}", toString (), t.getMessage ()), t); }} setStateAndfireevent (LifeCyclestate.initialized); } защищенный абстрактный void init0 () бросает LifeCycleException; / * * @see ilifecycle#start () */ @override public final Synchronized void start () Throws LifeCycleException {if (состояние == LifeCyclestate.new) {init (); } if (state! = LifeCyclestate.initialized) {return; } setStateAndfireevent (LifeCyclestate.starting); try {start0 (); } catch (throwable t) {setStateAndfireevent (LifeCyclestate.failed); if (t ancessionof LifeCycleException) {Throw (LifeCycleException) t; } else {Throw New LifeCycleException (formatString ("Не удалось запустить {0}, ошибка msg: {1}", toString (), t.getMessage ()), t); }} setStateAndfireevent (LifeCyclestate.started); } защищенный абстрактный void start0 () бросает LifeCycleException; / * * @see ilifecycle#suprend () */ @override public final Synchronized void suppend () Throws LifeCycleException {if (состояние == LifeCyclestate.suspending || state == LifeCycyClestate.suspended) {return; } if (state! = lifecyclestate.started) {return; } setStateAndfireevent (LifeCyclestate.suspending); try {suppust0 (); } catch (throwable t) {setStateAndfireevent (LifeCyclestate.failed); if (t ancessionof LifeCycleException) {Throw (LifeCycleException) t; } else {бросить новое LifeCycleException (formatString ("Не удалось приостановить {0}, ошибка msg: {1}", toString (), t.getMessage ()), t); }} setStateAndfireevent (LifeCyclestate.susped); } защищенный абстрактный void suprend0 () бросает LifeCycleException; / * * @see ilifecycle#resume () */ @override public final Synchronized void resume () бросает LifeCycleException {if (state! = LifeCyclestate.susped) {return; } setStateAndfireevent (LifeCyclestate.Resuming); попробуйте {resume0 (); } catch (throwable t) {setStateAndfireevent (LifeCyclestate.failed); if (t ancessionof LifeCycleException) {Throw (LifeCycleException) t; } else {бросить новое LifeCycleException (formatString ("Не удалось возобновить {0}, ошибка msg: {1}", toString (), t.getMessage ()), t); }} setStateAndfireevent (LifeCyclestate.Resumed); } защищенный абстрактный void resume0 () бросает LifeCycleException; / * * @see ilifecycle#destress () */ @override public final Synchronized void destress () бросает LifeCycleException {if (состояние == LifeCyclestate.destroying || state == LifeCyclestate.destroyed) {return; } setStateAndfireevent (LifeCyclestate.destroying); попробуйте {destroy0 (); } catch (throwable t) {setStateAndfireevent (LifeCyclestate.failed); if (t ancessionof LifeCycleException) {Throw (LifeCycleException) t; } else {бросить новое LifeCycleException (formatString ("Не удалось уничтожить {0}, ошибка msg: {1}", toString (), t.getMessage ()), t); }} setStateAndfireevent (LifeCyclestate.destroyed); } защищенный абстрактный void destry0 () бросает LifeCycleException; / * * @see * ilifecycle#addlifecyclelistener (ilifecyclelistener) */ @override public void addlifecyclelistener (ilifecyclelistener слушатель) {слушатель.add (слушатель); } / * * @see * ilifecycle#removelistener (ilifecyclelistener) * / @override public void removelifecyclelistener (ilifecyclelistener слушатель) {слушатель.remove (слушатель); } private void FireLifeCycleEvent (событие LifeCycleEvent) {for (iterator <ilifecyclelistener> it = слушатель. Слушатель.lifecycleevent (Event); }} защищенный синхронизированный жизненный циклстат getState () {return state; } Частный синхронизированный void setStateAndfireevent (LifeCyclestate NewState) бросает LifeCycleException {state = newState; FireLifeCycLeevent (New LifeCycleevent (State)); } private String FormatString (String Pattern, Object ... Arguments) {return messageformat.format (pattern, arguments); } / * * @see java.lang.object#toString () * / @Override public String toString () {return getClass (). getSiMplename (); }}Можно видеть, что внедрение скелета абстрактного класса делает несколько общих вещей в управлении жизненным циклом, проверяя, является ли переход между состояниями законным (например, он должен быть инициатор до начала), устанавливая внутреннее состояние и запускает соответствующий слушатель.
После того, как абстрактный класс реализует метод, определяемый Ilifecycle, он оставляет соответствующие абстрактные методы для его подкласса для реализации. Как показано в приведенном выше коде, оставшиеся абстрактные методы включают следующее:
Защищенный абстрактный void init0 () бросает LifeCycleException; Защищенный абстрактный void start0 () бросает LifeCycleException; Защищенная абстрактная void suspend0 () бросает LifeCycleException; Защищенное абстрактное void resume0 () бросает LifeCycleException; Защищенный абстрактный void destress0 () бросает LifeCycleException;
Элегантная реализация
До сих пор мы определили интерфейс ilifecycle, и его скелетный реализует AbstractLifeCycle и добавили механизм слушателя. Кажется, что мы можем начать писать класс, чтобы унаследовать абстрактный лифуцикл и переписать абстрактный метод, который он определяет, пока все хорошо.
Но прежде чем мы начнем, нам нужно рассмотреть несколько других вопросов.
Заинтересованы ли наши классы реализации во всех абстрактных методах?
Нужно ли каждая реализация для реализации init0, start0, suppend0, resume0, destroy0, destroy0?
Иногда наши живые классы или модули не поддерживают подвеску или выздоровление?
Непосредственное унаследование AbstractLifeCycl означает, что все его абстрактные методы должны быть реализованы.
Таким образом, нам также нужна реализация по умолчанию, DefaultLifeCycle, пусть он наследует AbstractLifeCycle и реализовать все абстрактные методы, но он не делает ничего практичного, ничего не делает. Просто давайте реализуем класс реализации наследуя этот класс реализации по умолчанию и переопределим метод интереса.
Итак, наш DefaultLifeCycle родился:
открытый класс defaultLifeCycle Extrable AbstractLifeCycle { / * @see abrdentlifecycle#init0 () * /@override protected void init0 () Throws LifeCycleException {// ничего не делать} / * * @see AbstractLifeCycle#start0 () * / @ @void vestex void startempecte roudecle {) * * @See AbstractLifeCycle#Suprend0 () */ @Override Protected void suprendInternal () Throws LifeCycleException {// ничего не делать}/ * * @see AbstractLifeCycle#resume0 () */ @Override @Override Protected void Destry0 () бросает LifeCycleException {// ничего не делать}} Для DefaultLifeCycle ничего не делайте его ответственность.
Итак, мы можем написать наш собственный класс реализации, наследовать DefaultLifecycle и переписать эти интересующие методы жизненного цикла.
Например, у меня есть класс, который должен выполнять только некоторые задачи во время инициализации, запуска и разрушения, поэтому я могу написать это так:
Импорт java.io.ioexception; import java.net.serversocket; import java.net.socket; public class socketserver extends defaultlifecycle {private serversocket acceptor = null; частный порт int = 9527; / * * @see defaultlifecycle#init0 () */ @Override Protected void init0 () Throws LifeCycleException {try {acceptor = new Serversocket (port); } catch (ioException e) {бросить новое LifeCycleException (e); }} / * * @see defaultlifecycle#start0 () * / @override protected void start0 () throws LifeCycleException {socket Socket = null; try {socket = acceptor.accept (); // Сделайте что -нибудь с сокетом} catch (ioException e) {бросить новое LifeCycleException (e); } наконец {if (socket! = null) {try {socket.close (); } catch (ioException e) {// todo автоматически сгенерированный блок e.printstacktrace (); }}}}} / * * @see defaultlifecycle#destroy0 () * / @override protected void destress0 () бросает LifeCycleException {if (acceptor! = null) {try {acceptor.close (); } catch (ioException e) {// todo автоматически сгенерированный блок e.printstacktrace (); }}}} В Serversocket здесь init0 инициализирует прослушивание сокетов, стартовая 0 начинает получать подключение к сокетам, Destress0 разрушает прослушивание гнезда.
В соответствии с этим механизмом управления жизненным циклом мы будем легко управлять ресурсами, и не будет отключения ресурсов, и архитектура и модульность будут более четкими.
конец
До сих пор эта статья реализовала простой механизм управления жизненным циклом и дал все коды реализации. После этого весь исходный код будет размещен на GitHub. Пожалуйста, обратите внимание на обновление этой статьи.