//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

= Jetty Component Architecture

Applications that use the Jetty libraries (both client and server) create objects from Jetty classes and compose them together to obtain the desired functionalities.

A client application creates a `ClientConnector` instance, a `HttpClientTransport` instance and an `HttpClient` instance and compose them to have a working HTTP client that uses to call third party services.

A server application creates a `ThreadPool` instance, a `Server` instance, a `ServerConnector` instance, a `Handler` instance and compose them together to expose an HTTP service.

Internally, the Jetty libraries create even more instances of other components that also are composed together with the main ones created by applications.

The end result is that an application based on the Jetty libraries is a _tree_ of components.
In server application the root of the component tree is a `Server` instance, while in client applications the root of the component tree is an `HttpClient` instance.

Having all the Jetty components in a tree is beneficial in a number of use cases.
It makes possible to register the components in the tree as xref:arch/jmx.adoc[JMX MBeans] so that a JMX console can look at the internal state of the components.
It also makes possible to xref:troubleshooting/component-dump.adoc[dump the component tree] (and therefore each component's internal state) to a log file or to the console for xref:troubleshooting/index.adoc[troubleshooting purposes].
// TODO: add a section on Dumpable?

[[lifecycle]]
== Jetty Component Lifecycle

Jetty components typically have a life cycle: they can be started and stopped.
The Jetty components that have a life cycle implement the `org.eclipse.jetty.util.component.LifeCycle` interface.

Jetty components that contain other components implement the `org.eclipse.jetty.util.component.Container` interface and typically extend the `org.eclipse.jetty.util.component.ContainerLifeCycle` class.
`ContainerLifeCycle` can contain these type of components, also called __bean__s:

* _managed_ beans, `LifeCycle` instances whose life cycle is tied to the life cycle of their container
* _unmanaged_ beans, `LifeCycle` instances whose life cycle is _not_ tied to the life cycle of their container
* _POJO_ (Plain Old Java Object) beans, instances that do not implement `LifeCycle`

`ContainerLifeCycle` uses the following logic to determine if a bean should be _managed_, _unmanaged_ or _POJO_:

* the bean implements `LifeCycle`
** the bean is not started, add it as _managed_
** the bean is started, add it as _unmanaged_
* the bean does not implement `LifeCycle`, add it as _POJO_

When a `ContainerLifeCycle` is started, it also starts recursively all its managed beans (if they implement `LifeCycle`); unmanaged beans are not started during the `ContainerLifeCycle` start cycle.
Likewise, stopping a `ContainerLifeCycle` stops recursively and in reverse order all its managed beans; unmanaged beans are not stopped during the `ContainerLifeCycle` stop cycle.

Components can also be started and stopped individually, therefore activating or deactivating the functionalities that they offer.

Applications should first compose components in the desired structure, and then start the root component:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=start]
----

The component tree is the following:

[,screen]
----
Root
├── Monitor (MANAGED)
└── Service (MANAGED)
    └── ScheduledExecutorService (POJO)
----

When the `Root` instance is created, also the `Monitor` instance is created and added as bean, so `Monitor` is the first bean of `Root`.
`Monitor` is a _managed_ bean, because it has been explicitly added to `Root` via `ContainerLifeCycle.addManaged(...)`.

Then, the application creates a `Service` instance and adds it to `Root` via `ContainerLifeCycle.addBean(...)`, so `Service` is the second bean of `Root`.
`Service` is a _managed_ bean too, because it is a `LifeCycle` and at the time it was added to `Root` is was not started.

The `ScheduledExecutorService` within `Service` does not implement `LifeCycle` so it is added as a _POJO_ to `Service`.

It is possible to stop and re-start any component in a tree, for example:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=restart]
----

`Service` can be stopped independently of `Root`, and re-started.
Starting and stopping a non-root component does not alter the structure of the component tree, just the state of the subtree starting from the component that has been stopped and re-started.

`Container` provides an API to find beans in the component tree:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=getBeans]
----

You can add your own beans to the component tree at application startup time, and later find them from your application code to access their services.

[TIP]
====
The component tree should be used for long-lived or medium-lived components such as thread pools, web application contexts, etc.

It is not recommended adding to, and removing from, the component tree short-lived objects such as HTTP requests or TCP connections, for performance reasons.

If you need component tree features such as automatic xref:arch/jmx.adoc[export to JMX] or xref:troubleshooting/component-dump.adoc[dump capabilities] for short-lived objects, consider having a long-lived container in the component tree instead.
You can make the long-lived container efficient at adding/removing the short-lived components using a data structure that is not part of the component tree, and make the long-lived container handle the JMX and dump features for the short-lived components.
====

[[listener]]
== Jetty Component Listeners

A component that extends `AbstractLifeCycle` inherits the possibility to add/remove event _listeners_ for various events emitted by components.

A component that implements `java.util.EventListener` that is added to a `ContainerLifeCycle` is also registered as an event listener.

The following sections describe in details the various listeners available in the Jetty component architecture.

[[listener-lifecycle]]
=== LifeCycle.Listener

A `LifeCycle.Listener` emits events for life cycle events such as starting, stopping and failures:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=lifecycleListener]
----

For example, a life cycle listener attached to a `Server` instance could be used to create (for the _started_ event) and delete (for the _stopped_ event) a file containing the process ID of the JVM that runs the `Server`.

[[listener-container]]
=== Container.Listener

A component that implements `Container` is a container for other components and `ContainerLifeCycle` is the typical implementation.

A `Container` emits events when a component (also called _bean_) is added to or removed from the container:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=containerListener]
----

A `Container.Listener` added as a bean will also be registered as a listener:

[,java,indent=0]
----
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java[tags=containerSiblings]
----

[[listener-inherited]]
=== Container.InheritedListener

A `Container.InheritedListener` is a listener that will be added to all descendants that are also ``Container``s.

Listeners of this type may be added to the component tree root only, but will be notified of every descendant component that is added to or removed from the component tree (not only first level children).

The primary use of `Container.InheritedListener` within the Jetty Libraries is `MBeanContainer` from the xref:arch/jmx.adoc[Jetty JMX support].

`MBeanContainer` listens for every component added to the tree, converts it to an MBean and registers it to the MBeanServer; for every component removed from the tree, it unregisters the corresponding MBean from the MBeanServer.
