Hasor 自定義作用域

2018-10-07 09:49 更新

我們以 HttpSession 為例,通過實(shí)際例子向大家展示。如何通過Hasor Scope 實(shí)現(xiàn)一個 HttpSession 作用域。

public class SessionScope implements Scope{
    private static final ThreadLocal<HttpSession> session 
        = new ThreadLocal<HttpSession>();

    public <T> Provider<T> scope(Object key, Provider<T> provider) {
        HttpSession httpSession = session.get();
        if (httpSession == null) {
            return provider;
        }
        String keyStr = "session_scope_" + key.toString();
        Object attribute = httpSession.getAttribute(keyStr);
        Provider<T> finalProvider = provider;
        if (attribute == null) {
            httpSession.setAttribute(keyStr, provider);
        } else {
            finalProvider = (Provider<T>) httpSession.getAttribute(keyStr);
        }
        return finalProvider;
    }
}


在例子中為了避免保存到 Session 中的 Bean 和本身 Session 中的數(shù)據(jù) key 出現(xiàn)沖突,我們特意加了一個前綴用于區(qū)分。


現(xiàn)在作用域的功能是有了,但是我們的 HttpSession 對象的還沒有做初始化。這次我們來實(shí)現(xiàn) Filter 接口,在每次 request 請求到來的時候把 Session 都更新到 ThreadLocal 中。在訪問結(jié)束之后再把 ThreadLocal 清理掉。


下面來看改造了之后的 Scope 代碼:

public class SessionScope implements Scope, Filter {
    private static final ThreadLocal<HttpSession> session
     = new ThreadLocal<HttpSession>();

    public void init(FilterConfig filterConfig) { ... }
    public void destroy() { ... }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        try {
            if (session.get() != null) {
                session.remove();
            }
            session.set(((HttpServletRequest) request).getSession(true));
            chain.doFilter(request, response);
        } finally {
            if (session.get() != null) {
                session.remove();
            }
        }
    }

    public <T> Provider<T> scope(Object key, Provider<T> provider) {
        HttpSession httpSession = session.get();
        if (httpSession == null) {
            return provider;
        }
        String keyStr = "session_scope_" + key.toString();
        Object attribute = httpSession.getAttribute(keyStr);
        Provider<T> finalProvider = provider;
        if (attribute == null) {
            httpSession.setAttribute(keyStr, provider);
        } else {
            finalProvider = (Provider<T>) httpSession.getAttribute(keyStr);
        }
        return finalProvider;
    }
}


從上面例子代碼中看到進(jìn)入 filter 時做了 Session 的初始化將其保存到 ThreadLocal ,離開之后又把 ThreadLocal 清理掉。


最后我們在 Hasor 初始化的時候把 Scope 配置到 Hasor 中:

public class StartModule extends WebModule {
    public void loadModule(WebApiBinder apiBinder) throws Throwable {
        ...
        SessionScope scope = new SessionScope();
        apiBinder.filter("/*").through(0, scope);
        apiBinder.registerScope("session", scope);
        ...
    }
}


接下來使用這個 Scope:

apiBinder.bindType(UserInfo.class).toScope(new SessionScope());
//or
apiBinder.bindType(UserInfo.class).toScope("session");


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號