[[lifecycle]]

== Lifecycle of contextual instances

The lifecycle of a contextual instance of a bean is managed by the context object for the bean's scope, as defined in <<contexts>>.

Every bean in the system is represented by an instance of the `Bean` interface defined in <<bean>>.
This interface is a subtype of `Contextual`. To create and destroy contextual instances, the context object calls the `create()` and `destroy()` operations defined by the interface `Contextual`, as defined in <<contextual>>.

[[bean_instantiation_restriction]]

=== Restriction upon bean instantiation

There are very few programming restrictions upon the bean class of a bean.
In particular, the class is a concrete class and is not required to implement any special interface or extend any special superclass.
Therefore, bean classes are easy to instantiate and unit test.

However, if the application directly instantiates a bean class, instead of letting the container perform instantiation, the resulting instance is not managed by the container and is not a contextual instance as defined by <<contextual_instance>>.
Furthermore, the capabilities listed in <<capabilities>> will not be available to that particular instance. In a deployed application, it is the container that is responsible for instantiating beans and initializing their dependencies.

If the application requires more control over instantiation of a contextual instance, a producer method or field may be used.
Any Java object may be returned by a producer method or field.
It is not required that the returned object be a contextual reference for a bean.
However, if the object is not a contextual reference for another bean, the object will be contextual instance of the producer method bean, and therefore available for injection into other objects and use in name resolution, but the other capabilities listed in <<capabilities>> will not be available to the object.

In the following example, a producer method returns instances of other beans:

[source, java]
----
@SessionScoped
public class PaymentStrategyProducer implements Serializable {
   
   private PaymentStrategyType paymentStrategyType;
   
   public void setPaymentStrategyType(PaymentStrategyType type) {
      paymentStrategyType = type;
   }

   @Produces PaymentStrategy getPaymentStrategy(@CreditCard PaymentStrategy creditCard,
                                                @Cheque PaymentStrategy cheque,
                                                @Online PaymentStrategy online) {
      switch (paymentStrategyType) {
         case CREDIT_CARD: return creditCard;
         case CHEQUE: return cheque;
         case ONLINE: return online;
         default: throw new IllegalStateException();
      }    
    }

}
----

In this case, any object returned by the producer method has already had its dependencies injected, receives lifecycle callbacks and event notifications and may have interceptors.

But in this example, the returned objects are not contextual instances:

[source, java]
----
@SessionScoped
public class PaymentStrategyProducer implements Serializable {
   
   private PaymentStrategyType paymentStrategyType;

   public void setPaymentStrategyType(PaymentStrategyType type) {
      paymentStrategyType = type;
   }

   @Produces PaymentStrategy getPaymentStrategy() {
      switch (paymentStrategyType) {
         case CREDIT_CARD: return new CreditCardPaymentStrategy();
         case CHEQUE: return new ChequePaymentStrategy();
         case ONLINE: return new OnlinePaymentStrategy();
         default: throw new IllegalStateException();
      }    
    }

}
----

In this case, any object returned by the producer method will not have any dependencies injected by the container, receives no lifecycle callbacks or event notifications and does not have interceptors or decorators.

[[biz_method]]

=== Container invocations and interception

When the application invokes:

* a method of a bean via a contextual reference to the bean, as defined in <<contextual_reference>>,
* a method of a bean via a non-contextual reference to the bean, if the instance was created by the container (e.g. using  `InjectionTarget.produce()` or `UnmanagedInstance.produce()`), or
* a method of a bean via a non-contextual reference to the bean, if the instance was enhanced with the `InterceptionFactory` interface as defined in <<interception_factory>>,

the invocation is treated as a _business method invocation_.

When the container invokes a method of a bean, the invocation may or may not be treated as a business method invocation:

* Invocations of initializer methods by the container are not business method invocations.
* Invocations of producer, disposer and observer methods by the container are business method invocations and are intercepted by method interceptors and decorators.
* Invocation of lifecycle callbacks by the container are not business method invocations, but are intercepted by interceptors for lifecycle callbacks.
* Invocations of interceptors and decorator methods during method or lifecycle callback interception are not business method invocations, and therefore no recursive interception occurs.
* Invocations of methods declared by java.lang.Object are not business method invocations.

A method invocation passes through method interceptors and decorators if, and only if, it is a business method invocation.

Otherwise, the invocation is treated as a normal Java method call and is not intercepted by the container.

[[contextual_instance_lifecycle]]

=== Lifecycle of contextual instances

The actual mechanics of bean creation and destruction varies according to what kind of bean is being created or destroyed.

[[managedbeanlifecycle]]

[[managed_bean_lifecycle]]

==== Lifecycle of managed beans

When the `create()` method of the `Bean` object that represents a managed bean is called, the container obtains an instance of the bean, as defined by the Managed Beans specification, calling the bean constructor as defined by <<instantiation>>, and performing dependency injection as defined in <<fields_initializer_methods>>.

When the `destroy()` method is called, the container destroys the instance, as defined by the Managed Beans specification, and any dependent objects, as defined in <<dependent_objects_destruction>>.



[[producer_method_lifecycle]]

==== Lifecycle of producer methods

When the `create()` method of a `Bean` object that represents a producer method is called, the container must invoke the producer method as defined by <<producer_or_disposer_methods_invocation>>.
The return value of the producer method, after method interception completes, is the new contextual instance to be returned by `Bean.create()`.

If the producer method returns a null value and the producer method bean has the scope `@Dependent`, the `create()` method returns a null value.

Otherwise, if the producer method returns a null value, and the scope of the producer method is not `@Dependent`, the `create()` method throws an `IllegalProductException`.

When the `destroy()` method is called, and if there is a disposer method for this producer method, the container must invoke the disposer method as defined by <<producer_or_disposer_methods_invocation>>, passing the instance given to `destroy()` to the disposed parameter.
Finally, the container destroys dependent objects, as defined in <<dependent_objects_destruction>>.

[[producer_field_lifecycle]]

==== Lifecycle of producer fields

When the `create()` method of a `Bean` object that represents a producer field is called, the container must access the producer field as defined by <<producer_fields_access>> to obtain the current value of the field.
The value of the producer field is the new contextual instance to be returned by `Bean.create()`.

If the producer field contains a null value and the producer field bean has the scope `@Dependent`, the `create()` method returns a null value.

Otherwise, if the producer field contains a null value, and the scope of the producer field is not `@Dependent`, the `create()` method throws an `IllegalProductException`.

When the `destroy()` method is called, and if there is a disposer method for this producer field, the container must invoke the disposer method as defined by <<producer_or_disposer_methods_invocation>>, passing the instance given to `destroy()` to the disposed parameter.

