自定义作用域
以 HttpSession 为例,实现一个 HttpSession 作用域。
- public class SessionScope implements Scope {
- public 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;
- }
- // 为了避免保存到 Session 中的 Bean 和本身 Session 中的数据 key
- // 出现冲突,增加一个前缀用于区分
- 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;
- }
- }
然后通过一个 Filter 每次 request 请求到来的时候把 Session 对象设置到 ThreadLocal 中。
- public class ConfigSession implements Filter {
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- try {
- if (SessionScope.session.get() != null) {
- SessionScope.session.remove();
- }
- SessionScope.session.set(((HttpServletRequest) request).getSession(true));
- chain.doFilter(request, response);
- } finally {
- if (SessionScope.session.get() != null) {
- SessionScope.session.remove();
- }
- }
- }
- }
最后我们在创建 Hasor 的时候把 Scope 配置上,这里由于要配置 Filter 因此使用 WebModule
- public class StartModule extends WebModule {
- public void loadModule(WebApiBinder apiBinder) throws Throwable {
- ...
- apiBinder.filter("/*").through(0, new ConfigSession());
- apiBinder.registerScope("session", new SessionScope());
- ...
- }
- }
接下来配置每次创建 UserInfo 对象时都是 Session 内唯一:
- apiBinder.bindType(UserInfo.class).toScope("session");