Skip to content

Latest commit

 

History

History
140 lines (121 loc) · 4.51 KB

File metadata and controls

140 lines (121 loc) · 4.51 KB

CDI Injection

In order to use ManagedExecutor and ThreadContext as CDI beans, define producer for them as @ApplicationScoped so that instances are shared and reused. In most cases, more granular and shorter-lived scopes are undesirable. For instance, having a new ManagedExecutor instance created per HTTP request typically does not make sense. In the event that a more granular scope is desired, the application must take care to supply a disposer to ensure that the executor is shut down once it is no longer needed. When using application scope, it is optional to supply a disposer because the specification requires the container to automatically shut down ManagedExecutor instances when the application stops.

Example Producer for ManagedExecutor

Example qualifier,

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
public @interface SecurityAndCDIContext {}

Example producer and disposer,

import org.eclipse.microprofile.concurrent.ManagedExecutor;
import org.eclipse.microprofile.concurrent.ThreadContext;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;

@ApplicationScoped
public class MyFirstBean {
    @Produces @ApplicationScoped @SecurityAndCDIContext
    ManagedExecutor executor = ManagedExecutor.builder()
        .propagated(ThreadContext.SECURITY, ThreadContext.CDI)
        .build();

    void disposeExecutor(@Disposes @SecurityAndCDIContext ManagedExecutor exec) {
        exec.shutdownNow();
    }
}

Example injection point,

import org.eclipse.microprofile.concurrent.ManagedExecutor;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

@ApplicationScoped
public class MySecondBean {
    @Inject @SecurityAndCDIContext
    ManagedExecutor sameExecutor;
    ...
}

Example Producer for ThreadContext

Example qualifier,

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
public @interface AppContext {}

Example producer method,

import org.eclipse.microprofile.concurrent.ThreadContext;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;

@ApplicationScoped
public class MyFirstBean {
    @Produces @ApplicationScoped @AppContext
    createAppContextPropagator() {
        return ThreadContext.builder()
               .propagated(ThreadContext.APPLICATION)
               .cleared(ThreadContext.SECURITY, ThreadContext.TRANSACTION)
               .unchanged(ThreadContext.ALL_REMAINING)
               .build();
  }
}

Example injection point,

import org.eclipse.microprofile.concurrent.ThreadContext;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
...

@ApplicationScoped
public class MySecondBean {
    Function<Integer, Item> findItem;

    @Inject
    protected void setFindItem(@AppContext ThreadContext appContext) {
        findItem = appContext.contextualFunction(i -> {
            try (Connection con =
                 ((DataSource) InitialContext.doLookup("java:comp/env/ds1")).getConnection();
                 PreparedStatement stmt = con.prepareStatement(sql)) {
                stmt.setInt(1, i);
                return toItem(stmt.executeQuery());
            } catch (Exception x) {
                throw new CompletionException(x);
            }
        });
    }
    ...
}