> For the complete documentation index, see [llms.txt](https://boxlang.ortusbooks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://boxlang.ortusbooks.com/boxlang-framework/interceptors/core-interception-points/class-instance-events.md).

# Class Instance Events

Interception points announced when a BoxLang class instance is created and initialized

These events fire when a BoxLang class is instantiated through `new`, `createObject()`, deserialization, or any other path that bootstraps a BoxLang class. They are announced on the **global interceptor pool** and are available starting in BoxLang **1.18.0**.

Use them for dependency injection, auditing, observability, and AOP-style decoration of class instances.

| Event Name              | Cancellable | Description                                                                                                                     |
| ----------------------- | :---------: | ------------------------------------------------------------------------------------------------------------------------------- |
| `afterBoxClassCreation` |      No     | The instance is fully defined (pseudo-constructor ran, interfaces and abstract methods validated) but `init()` has **not** run. |
| `afterBoxClassInit`     |      No     | `init()` (or the implicit constructor) has completed.                                                                           |

* [`afterBoxClassCreation`](#afterboxclasscreation)
* [`afterBoxClassInit`](#afterboxclassinit)

{% hint style="info" %}
The data for these events is only built when at least one interceptor is listening, so they add no cost to class creation when unused.
{% endhint %}

## afterBoxClassCreation

Fired after the class instance is fully defined but **before** `init()` is called. The pseudo-constructor has run, and interfaces and abstract methods have been validated.

* It **also fires for `noInit` creations** such as `createObject()` and deserialization, where `init()` is never called. Check the `noInit` key to tell them apart.
* It **never fires for super classes** in an `extends` chain, only for the concrete instance being created.

### Data Structure

| Data Key    | Type             | Description                                             |
| ----------- | ---------------- | ------------------------------------------------------- |
| `instance`  | `IClassRunnable` | The BoxLang class instance.                             |
| `className` | `String`         | The name of the class.                                  |
| `noInit`    | `Boolean`        | `true` when `init()` will be skipped for this instance. |
| `context`   | `IBoxContext`    | The context the class is being created in.              |

### Example

```js
class {

    function afterBoxClassCreation( data ) {
        // Inject a dependency before init() runs
        if ( data.className contains "Service" ) {
            data.instance.getVariablesScope().logger = getLogger()
        }
    }

}
```

## afterBoxClassInit

Fired after `init()` (or the implicit constructor) completes.

* It **does not fire** for `noInit` creations, since `init()` never runs.
* It **does not fire** when `init()` throws an exception.

### Data Structure

| Data Key    | Type             | Description                                                                         |
| ----------- | ---------------- | ----------------------------------------------------------------------------------- |
| `instance`  | `IClassRunnable` | The BoxLang class instance.                                                         |
| `result`    | `Object`         | What construction returned: the instance, or whatever a non-null `init()` returned. |
| `className` | `String`         | The name of the class.                                                              |
| `context`   | `IBoxContext`    | The context the class is being created in.                                          |

### Example

```js
class {

    function afterBoxClassInit( data ) {
        writeLog( text="Created #data.className#", type="information" )
    }

}
```

{% hint style="warning" %}
These are announced on the global interceptor pool in the hot path of class instantiation. Keep handlers fast, and return early for classes you do not care about.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://boxlang.ortusbooks.com/boxlang-framework/interceptors/core-interception-points/class-instance-events.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
