Принцип загрузки веб-приложения в Tomcat 7 (1) Context Construction

Java задняя часть исходный код Tomcat

Зачем заботиться о процессе загрузки веб-приложения в Tomcat? Я много раз видел диаграмму структуры компонентов Tomcat в предыдущей статье, и я опубликую ее здесь для обзора:

предыдущийАнализ запуска Tomcat 7В серии статей, при запуске Tomcat будет парсить server.xml, инициализировать и запускать соответствующие компоненты один за другим согласно информации каждого сконфигурированного в нем узла (т.е. вызывать их методы init и start соответственно), но просмотрите исходный код Tomcat 7 для Содержимое server.xml соответствует компонентам на всех уровнях, которые были настроены по умолчанию на приведенном выше рисунке, включая сервер, службу, ядро, соединитель, хост и клапан. Компонент Context на рисунке выше на самом деле то, что мы обычно называем веб-приложением, Интересно то, что этот компонент не настроен в server.xml, и когда мы запускаем его по умолчанию, на самом деле есть несколько веб-приложений, к которым можно получить доступ. : Что, черт возьми, здесь происходит?

видел раньшеАнализ запросов Tomcat 7Люди в серии статей должны знать, что после того, как браузер отправит запрос на сервер Tomcat, он в конечном итоге найдет соответствующий объект контекста веб-приложения, доступ к которому осуществляется в соответствии с путем URL-адреса в браузере (по умолчаниюorg.apache.catalina.core.StandardContextэкземпляр класса). Например, доступен URL-адресhttp://localhost:8080/Затем будет отправлено в папку MAP представляет собой корневое веб-приложение, доступ к URLhttp://localhost:8080/docs, веб-приложение, представленное папкой docs, будет доступно. Итак, можно предположить, что после запуска Tomcat каждый объект контекста, представляющий соответствующее веб-приложение, должен быть создан внутри контейнера.

В этой статье исследуется этот вопрос. существуетПринцип отключения сервера Tomcat 7Как упоминалось в начале, в конфигурации по умолчанию после запуска Tomcat вы увидите, что на самом деле в фоновом режиме работает 6 потоков:

описано в предыдущих статьяхmain,http-bio-8080-Acceptor-0,http-bio-8080-AsyncTimeout,ajp-bio-8009-Acceptor-0,ajp-bio-8009-AsyncTimeout, рассказал о роли этих потоков, о том, как они порождают запросы и отвечают на них. Но есть один поток, который не говорит, т.е.ContainerBackgroundProcessor[StandardEngine[Catalina]], а загадка вопроса, на который предстоит ответить в этой статье, — в этой ветке.

Давайте сначала посмотрим, как генерируется этот поток. На самом деле, мы можем увидеть некоторые подсказки из названия. Он называется фоновым процессором контейнера и связан с StandardEngine. То же самое верно и для его функции.

Все компоненты контейнера по умолчанию (StandardEngine, StandardHost, StandardContext, StandardWrapper) в Tomcat 7 наследуют родительский класс.org.apache.catalina.core.ContainerBaseКогда сборка контейнера позвонит методу запуска MATTINDINDERNAL их внутри, внутри, как правило, вызывает метод startInternal (кроме стандартного standcontext реализованного класса) родительский класс, такой какorg.apache.catalina.core.StandardEngineМетод STARTINTERNAL в классе:

Последнийsuper.startInternal()То есть вызвать родительский классorg.apache.catalina.core.ContainerBase的startInternalметод, в конце метода:
Линия 6 комплектовLifecycleState.STARTINGстатус (это опубликуетLifecycle.START_EVENTсобытие), роль этой линии будет упомянута позже в этой статье, и пока она не будет указана. Строка 9 вызывает метод threadStart, посмотрите на код метода threadStart:
Здесь вы можете видеть, что если два условия предварительной проверки выполняются, поток будет запущен, и имя потока будет начинаться сContainerBackgroundProcessor[В начале после имени потока берется метод toString объекта, для примера возьмем StandardEngine, см.org.apache.catalina.core.StandardEngineРеализован метод toString:
Вышеизложенное объясняет происхождение этого фонового потока.

Но здесь есть проблема, так как StandardEngine и StandardHost будут вызыватьsuper.startInternal()метод, согласно конфигурации по умолчанию, фон должен генерировать два фоновых потока, почему только один?

назадorg.apache.catalina.core.ContainerBaseМетод threadStart имеет два условия проверки перед запуском кода потока:

Когда объект компонента контейнера инициализируется, потокnull, backgroundProcessorDelay — это-1
ноorg.apache.catalina.core.StandardEngineСделал небольшую модификацию в собственном конструкторе:
Наконец, конструктор устанавливает значение backgroundProcessorDelay родительского класса с помощью-1изменился на10, поэтому, когда Tomcat начинает анализировать xml и встречает узел Engine, соответственно будет сгенерирован поток фоновой обработки.

После разговора о создании этого потока фоновой обработки взгляните на то, что делает этот поток, а затем посмотрите на код запуска этого потока:

Итак, этот поток выполнит метод run внутреннего класса ContainerBackgroundProcessor, взгляните на полный код реализации ContainerBackgroundProcessor:
После того, как его метод run приостанавливается на некоторое время, вызывается метод processChildren, который делает две вещи: во-первых, вызывает метод backgroundProcess самого компонента-контейнера, но удаляет все компоненты-подконтейнеры компонента-контейнера. компонент-контейнер и вызвать их метод processChildren. Короче говоря, реализация этого потока заключается в периодическом рекурсивном вызове метода backgroundProcess текущего контейнера и всех его подконтейнеров.

И этот метод backgroundProcess был реализован внутри ContainerBase:

Этот код не будет объясняться по одному, если подытожить, то это вызов метода backgroundProcess других внутренних компонентов, связанных с контейнером, один за другим. Последняя регистрацияLifecycle.PERIODIC_EVENTсобытие.

Выше приведен обзор того, что делает поток фоновой обработки Tomcat 7. В более ранних версиях Tomcat были некоторые вещи фоновой обработки, которые изначально были настроены и запускались в каждом компоненте.В Tomcat 5 вся фоновая обработка была изменена. поделитесь той же темой.

Вернемся к вопросу, на который нужно ответить в этой статье: как веб-приложение загружается в контейнер? В конце метода backgroundProcess класса ContainerBase:

fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);  

зарегистрирован в контейнереPERIODIC_EVENTсобытие. Как упоминалось ранее, по умолчаниюContainerBackgroundProcessor[StandardEngine[Catalina]]Поток будет периодически (10 секунд по умолчанию) выполнять методы backgroundProcess компонентов контейнера Engine, Host, Context, Wrapper и связанных с ними компонентов, поэтому он также будет периодически публиковатьPERIODIC_EVENTсобытие, вот прослушиватель, связанный со StandardHostorg.apache.catalina.startup.HostConfig:

Когда Tomcat начинает анализировать xmlorg.apache.catalina.startup.CatalinaСтрока 386 класса:digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"))

В методе addRuleInstances класса HostRuleSet:

В строках с 9 по 12 видно, что все узлы Host добавляютorg.apache.catalina.startup.HostConfigобъект какorg.apache.catalina.core.StandardHostпрослушиватель объектов

В методе lifecycleEvent HostConfig вы можете увидеть ответ, если компонент Host получает публикацию события Lifecycle.PERIODIC_EVENT (если вам непонятен механизм жизненного цикла Tomcat 7, вы можете прочитать его нижеАнализ запуска Tomcat 7 (5) Механизм жизненного цикла и принцип реализации:

Строка 17, если опубликованное событиеPERIODIC_EVENTМетод проверки будет выполнен. Строка 19, если опубликованное событиеSTART_EVENTЗатем выполните метод запуска. И метод проверки, и метод запуска в конце вызовут метод deployApps(). Давайте посмотрим на реализацию этого метода:
Вот код для публикации веб-приложения различными способами.

Ранее в этой статье упоминалось, что по умолчанию компонент будет выпущен при запуске.Lifecycle.START_EVENTсобытие (вorg.apache.catalina.core.ContainerBaseМетод startInternal класса является предпоследней строкой), вернемся к методу lifecycleEvent HostConfig, поэтому метод start HostConfig будет выполняться по умолчанию, в конце метода:

if (host.getDeployOnStartup())  
    deployApps();

Поскольку конфигурация по умолчанию host.getDeployOnStartup() возвращает true , контейнер будет напрямую загружать соответствующее веб-приложение при запуске.

Конечно, если для атрибута deployOnStartup узла Host в server.xml задано значение false, приложение не будет загружено при запуске контейнера, и служба веб-приложения не может быть предоставлена ​​сразу после запуска. Но поскольку упомянутый выше поток фоновой обработки запущен, метод проверки HostConfig будет выполняться периодически:

Если свойство autoDeploy узла Host имеет значение true (настройка по умолчанию — true ), вы можете видеть, что метод проверки также загрузит веб-приложение в конце.