Java Context

In programmazione il contesto è l’insieme di tutte le informazioni che in qualche modo possono condizionare l’unità di lavoro corrente. Ad esempio l’ambiente di esecuzione utilizzato, le variabili di ambiente, le variabili di istanza, le variabili locali, lo stato di altre classi, lo stato dell’ambiente corrente, ecc. In molte librerie troviamo il contesto in interfacce o classi, come ad esempio ServletContext di Servlet, FacesContext di JSF, ApplicationContext di Spring, Context di Android, InitialContext di JNDI, ecc. Molto spesso seguono il pattern facade che astrae i dettagli implementativi che l’utilizzatore non ha bisogno di conoscere raggruppando tutti i metodo in una singola interfaccia o classe.

In questo articolo mostriamo una interessante implementazione di un contesto di esecuzione per le delle API web (es. SOAP o REST) che mantiene isolati i contesti di chiamate distinte, ovvero ciascuna chiamata opera su un proprio contesto che non è condiviso con le altre.

ThreadLocal

Per poter creare contesti distinti per ogni invocazione è necessario disporre di una funzionalità che consenta di gestire variabili che possono essere lette o scritte esclusivamente all’interno dello stesso thread. Questo perchè indipendentemente dal framework utilizzato (Jax-ws, Axis, Jax-rs, etc.) quello che accade è che ad ogni richiesta un nuovo thread viene creato o prelevato da un pool di thread esistenti per gestirla.

A tale scopo java ci mette a disposizione la classe java.lang.ThreadLoca che consente di creare variabili la cui visibilità è limitata ad un singolo thread. E’ sufficiente generare un oggetto ThreadLocal per tutti i thread e poi utilizzare i metodi get() e set() per accedere alla variabile. La particolarità è che anche se diversi thread accedono allo stesso oggetto ThreadLocal (magari nella stessa porzione di codice) comunque il valore che vedono è diverso da quello degli altri thread.

Contesto di Esecuzione

Vediamo quindi come sia possibile implementare un contesto di esecuzione per le richieste soap o rest utilizzando un oggetto ThreadLocal. In realtà nell’articolo JAX-WS Interceptor abbiamo già visto come fare ma ci siamo principalmente concentrati su come intercettare una richiesta. In quell’occasione abbiamo introdotto un oggetto RequestContextHolder così definito:

La classe espone solamente metodi statici che consentono di impostare il valore di un oggetto Header. In tale oggetto sono valorizzate informazioni di contesto che in generale poco hanno a che fare con il metodo invocato dal client della nostra ipotetica interfaccia webservice e che probabilmente non vogliamo trasferire ai metodi che poi vengono effettivamente invocati nel nostro servizio.

Questo non significa che in un qualche punto del nostro codice non ci sia la necessità di accedere all’oggetto Header ma mantenendolo isolato nella variabile ThreadLocal possiamo accedervi immediatamente utilizzando il relativo metodo get().

In un prossimo articolo vedremo come utilizzando l’interceptor presentato in JAX-WS Interceptor ed il contesto RequestContextHolder per implementare un nuovo scope di Spring.

 

How useful was this post?

Click on a star to rate it!

Average rating 3 / 5. Vote count: 4

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!