Logic for how interceptors & decorators work in OWB.
- 1- Configuration of decorators and interceptors
Decorators and Interceptors are configured from {@link org.apache.webbeans.config.BeansDeployer}class via methods defineManagedBean(class)
and Those methods further call defineInterceptor(interceptor class)
and defineDecorator(decorator class)
methods. Those methods finally call {@link org.apache.webbeans.util.WebBeansUtil#defineInterceptor(org.apache.webbeans.component.creation.ManagedBeanCreatorImpl,javax.enterprise.inject.spi.ProcessInjectionTarget)} and{@link org.apache.webbeans.util.WebBeansUtil#defineDecorator(org.apache.webbeans.component.creation.ManagedBeanCreatorImpl,javax.enterprise.inject.spi.ProcessInjectionTarget)}methods for actual configuration.
Let's look at the "WebBeansUtil's" methods;
-
defineInterceptor
: This method firstly creates a "Managed Bean" for the given interceptor with "WebBeansType.INTERCEPTOR" as a type. After checking some controls, it calls "WebBeansInterceptorConfig#configureInterceptorClass". "configureInterceptorClass" method creates a "WebBeansInterceptor" instance that wraps the given managed bean instance and configuring interceptor's *Interceptor Binding* annotations. If everything goes well, it adds interceptor instance into the "BeanManager" interceptor list. defineDecorator
: Exactly doing same thing as "defineInterceptor". If everything goes well, it adds decorator instance into the "BeanManager" decorator list.
2* Configuring ManagedBean Instance Interceptor and Decorator Stack Currently interceptors and decorators are supported for the "Managed Beans". OWB delegates calling of "EJB Beans" interceptors to the EJB container. It does not provide built-in interceptor and decorator support for EJB beans. Current implementation supports configuration of the interceptors on the "Managed Beans" with 2 different scenarios, i.e. it supports "EJB related interceptors ( defined by EJB specification)" and "JSR-299 related interceptors (defined by interceptor bindings)". Managed Beans interceptor and decorator stacks are configured after they are instantiated by the container first time. This method can be found in the AbstractInjectionTargetBean" class "afterConstructor()" method. Actual configuration is done by the {@link org.apache.webbeans.config.DefinitionUtil#defineBeanInterceptorStack(org.apache.webbeans.component.AbstractInjectionTargetBean)} and{@link org.apache.webbeans.config.DefinitionUtil#defineDecoratorStack}. In "DefinitionUtil.defineBeanInterceptorStack", firstly it configures "EJB spec. interceptors" after that configures "JSR-299 spec. interceptors." In "DefinitionUtil.defineDecoratorStack", it configures decorator stack. "EJBInterceptorConfig" class is responsible for finding all interceptors for given managed bean class according to the EJB Specification. (But as you said, it may not include AroundInvoke/PostConstruct etc. disablement scenario!). "WebBeansInterceptorConfig" class is responsible for finding all interceptors for a given managed bean class according to the "JSR-299, spec." It adds all interceptors into the bean's interceptor stack. It first adds "EJB" related interceptors, after that adds "JSR-299" related interceptors. For "JSR-299" related interceptors, it orders the interceptors according to the "InterceptorComparator". Basically, it puts interceptors in order according to how they are ordered in a "beans.xml" configuration file. Similarly, it configures managed bean's decorator stack according to the decorator resolution rules. Also, it orders decorators according to the "beans.xml" configuration file that contains decorator declarations.
3* Invocation of Interceptors and Decorators Invocation is handled by the "InterceptorHandler" class (It has an absurd name, it can be changed to a more meaningful name :)). It works nearly same as what you have explained. First of all, it checks that calling method is a business method of a managed bean or not. After that it filters interceptor stack for calling method (Current design of filtering may not be optimal!). Firstly it adds EJB interceptor to the list and then adds JSR-299 interceptors. After that, it starts to call all interceptors in order. After consuming all interceptors it calls decorators. (as you explained, seems that the logic may not be correct here. Currently, interceptors and decorators are not related with each other. They are called independently).This must be changed!.
@version $Rev: 1366640 $ $Date: 2012-07-28 13:24:18 +0200 (Sa, 28 Jul 2012) $
@see WebBeansInterceptorConfig
@see WebBeansDecoratorConfig
@see org.apache.webbeans.intercept.webbeans.WebBeansInterceptor
@see org.apache.webbeans.decorator.WebBeansDecorator
@see org.apache.webbeans.intercept.ejb.EJBInterceptorConfig