+

Search Tips   |   Advanced Search

Develop contextual proxies

Use a work manager as a ContextService to contextualize invocation of an interface.

Application components that require thread context to be present when methods of an object are invoked can use a work manager, which implements javax.enterprise.concurrent.ContextService, to construct a contextual proxy for the object. Thread context is captured, per the settings of the work manager, when the contextual proxy is created. When interface methods are invoked on the contextual proxy, the previously captured thread context is applied prior to invocation and restored afterward.


Tasks

  1. Define an interface (or choose an existing interface that is suitable) with the methods that require thread context.
    public interface AddressFinder {
        Address getAddress(Person p) throws Exception;
    }
    

  2. Provide an implementation of the interface:
    public class DatabaseAddressFinder implements AddressFinder {
        private final String resRefLookupName;
        public DatabaseAddressFinder(String resRefLookupName) {
            this.resRefLookupName = resRefLookupName;
        }
        public Address getAddress(Person p) throws Exception {
            // Resource reference lookup requires the thread context of the
            // application component that defines the resource reference.
            DataSource ds = (DataSource) new InitialContext().lookup(
                resRefLookupName);
            Connection con = ds.getConnection();
            try {
                ResultSet r = con.createStatement().executeQuery(
                    "SELECT STREETADDR, CITY, STATE, ZIP " +
                    "FROM ADDRESSES WHERE PERSONID=" + p.id);
                if (r.next())
                    return new Address(r.getString(1), r.getString(2),
                        r.getString(3), r.getInt(4));
                else
                    return null;
            } finally {
                con.close();
            }
        }
    }
    

  3. Use a context service to capture context from the current thread and wrap an instance with that context:
    ContextService contextService = (ContextService) new InitialContext().lookup(
        "java:comp/DefaultContextService");
    AddressFinder addressFinder = contextService.createContextualProxy(
        new DatabaseAddressFinder("java:comp/env/jdbc/MyDataSourceRef"),
        AddressFinder.class);
    

  4. From another thread, use the contextual proxy to invoke methods under the context of the original thread.
    Address myAddress = addressFinder.getAddress(me);
    


Subtopics