jakarta.enterprise.inject.spi.InterceptionFactory Maven / Gradle / Ivy
Show all versions of jakarta.enterprise.cdi-api Show documentation
/*
* Copyright 2016, Red Hat, Inc., and individual contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jakarta.enterprise.inject.spi;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.UnproxyableResolutionException;
import jakarta.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
/**
* {@link InterceptionFactory} allows to create a wrapper instance whose method invocations are intercepted by method
* interceptors and forwarded to a provided instance.
*
*
* An implementation of {@link InterceptionFactory} may be obtained by calling
* {@link BeanManager#createInterceptionFactory(CreationalContext, Class)} to be used in the create method of a custom bean for
* example.
*
*
*
* public class MyCustomBean implements Bean<MyClass> {
*
* BeanManager bm;
*
* public MyCustomBean(BeanManager bm) {
* this.bm = bm;
* }
*
* public MyClass create(CreationalContext<MyClass> creationalContext) {
*
* InterceptionFactory<MyClass> factory = bm.createInterceptionFactory(creationalContext, MyClass.class);
*
* factory.configure().filterMethods(m -> m.getJavaMember().getName().equals("shouldBeTransactional")).findFirst()
* .ifPresent(m -> m.add(new AnnotationLiteral<Transactional>() {
* }));
*
* return factory.createInterceptedInstance(new MyClass());
* }
* }
*
*
*
* The container must also provide a built-in bean with scope {@link Dependent}, bean type {@link InterceptionFactory} and
* qualifier {@link Default} that can be injected in a producer method parameter.
*
*
*
* @Produces
* @RequestScoped
* public MyClass produceMyClass(InterceptionFactory<MyClass> factory) {
* factory.configure().add(new AnnotationLiteral<Transactional>() {
* });
* return factory.createInterceptedInstance(new MyClass());
* }
*
*
*
* Instances of this class are neither reusable nor suitable for sharing between threads.
*
*
*
* CDI Lite implementations are not required to provide support for {@code InterceptionFactory}.
*
*
* @author Antoine Sabot-Durand
* @since 2.0
* @param type for which the wrapper is created
*/
public interface InterceptionFactory {
/**
* Instructs the container to ignore all non-static, final methods with public, protected or default visibility declared by
* any class in the type hierarchy of the intercepted instance during invocation of
* {@link #createInterceptedInstance(Object)}.
*
*
* Ignored methods should never be invoked upon the wrapper instance created by
* {@link #createInterceptedInstance(Object)}. Otherwise, unpredictable behavior results.
*
*
* @return self
*/
InterceptionFactory ignoreFinalMethods();
/**
* Returns an {@link AnnotatedTypeConfigurator} initialized with the {@link AnnotatedType} created either for the class
* passed to {@link BeanManager#createInterceptionFactory(CreationalContext, Class)} or derived from the
* {@link InterceptionFactory} parameter injection point.
*
*
* The configurator allows to add or remove interceptor bindings used to associate interceptors with the wrapper instance
* returned by {@link #createInterceptedInstance(Object)}.
*
*
*
* Each call returns the same {@link AnnotatedTypeConfigurator}.
*
*
* @return an {@link AnnotatedTypeConfigurator} to configure interceptors bindings
*/
AnnotatedTypeConfigurator configure();
/**
* Returns a wrapper instance whose method invocations are intercepted by method interceptors and forwarded to a provided
* instance.
*
*
* This method should only be called once, subsequent calls will throw an {@link IllegalStateException}.
*
*
*
* If T is not proxyable as defined in section 3.11 of the spec an
* {@link UnproxyableResolutionException} exception is thrown. Calling {@link #ignoreFinalMethods()}
* before this method can loosen these restrictions.
*
*
*
* If the provided instance is an internal container construct (such as client proxy), non-portable behavior results.
*
*
* @param instance The provided instance
* @return a wrapper instance
*/
T createInterceptedInstance(T instance);
}