SpringBoot2(15)踩坑之Sping5中SpringWebContext方法过时

SpringWebContext方法过时

今天在做项目的时候,为了优化访问速度,应对高并发,想把页面信息全部获取出来存到redis缓存中,这样每次访问就不用客户端进行渲染了,速度能快不少。

想用thymeleafViewResolver.getTemplateEngine().process("goodslist.html",ctx);函数实现,里面有一个ctx参数,这个参数就是WebContext

然后定义这个变量 SpringWebContext ctx = new SpringWebContext(......)

哎,这个方法在SpringBoot1.X的时候还能有,在org.thymeleaf.spring4.context这个package下,在、SpringBoot2.X +thymeleaf3.0.9 中没有,想去找一下用什么来代替,直接去org.thymeleaf.spring4下面去找,没找到相同类型的,然后取找thymeleaf.spring5的API,还找不到,只能找到thymeleaf.spring4的API,。想想还要用,怎么办啊,总不能把版本切换了吧,那有些别的说不定也得改,自己写吧,自力更生艰苦奋斗。

找了之前的一个项目,然后找到了那里面的SpringWebContext是怎么写的,超过来就完了,

但是不行SpringWebContext继承的是org.thymeleaf.context下的WebContext方法,在SpringBoot2.0+thymeleaf3.0.9中定义成final类型的,不能继承,想想要不把库的代码改了,还是算了,再往上找,找到这个WebContext extends AbstractContext implements IWebContext,没有final,所以一层一层的找到之后,按照他的源码改了一下,自己重写了SpringWebContext方法,如下

package com.springboot.SecKill.util;

import org.springframework.context.ApplicationContext;
import org.thymeleaf.context.AbstractContext;
import org.thymeleaf.context.IWebContext;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author WilsonSong
 * @date 2018/8/5
 */
public class SpringWebContextUtil  extends AbstractContext implements IWebContext {

    private final HttpServletRequest request;
    private final HttpServletResponse response;
    private final ServletContext servletContext;

    public static final String BEANS_VARIABLE_NAME = "beans";
    private static final ConcurrentHashMap<ApplicationContext, HashMap<String, Object>> variableMapPrototypes = new ConcurrentHashMap();
    private final ApplicationContext applicationContext;

    public SpringWebContextUtil(final HttpServletRequest request,
                                final HttpServletResponse response,
                                final ServletContext servletContext,
                                final Locale locale,
                                final Map<String, Object> variables,
                                final ApplicationContext appctx){
        super(locale,addSpringSpecificVariables(variables, appctx));
        this.request = request;
        this.response = response;
        this.servletContext = servletContext;
        this.applicationContext = appctx;

    }

    private static Map<String, Object> addSpringSpecificVariables(Map<String, ?> variables, ApplicationContext appctx) {
        HashMap<String, Object> variableMapPrototype = (HashMap)variableMapPrototypes.get(appctx);
        if (variableMapPrototype == null) {
            variableMapPrototype = new HashMap(20, 1.0F);
            ContexBeans beans = new ContexBeans(appctx);
            variableMapPrototype.put("beans", beans);
            variableMapPrototypes.put(appctx, variableMapPrototype);
        }

        Map newVariables;
        synchronized(variableMapPrototype) {
            newVariables = (Map)variableMapPrototype.clone();
        }

        if (variables != null) {
            newVariables.putAll(variables);
        }

        return newVariables;
    }

    public ApplicationContext getApplicationContext() {
        return this.applicationContext;
    }

    public HttpServletRequest getRequest() {
        return this.request;
    }

    public HttpSession getSession() {
        return this.request.getSession(false);
    }

    public HttpServletResponse getResponse() {
        return this.response;
    }

    public ServletContext getServletContext() {
        return this.servletContext;
    }
}

其中的ContexBeans是自己定义的,如下:

package com.springboot.SecKill.util;

/**
 * @author WilsonSong
 * @date 2018/8/5
 */

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.springframework.context.ApplicationContext;
import org.thymeleaf.util.Validate;
public class ContexBeans implements Map<String, Object> {
    private final ApplicationContext ctx;

    public ContexBeans(ApplicationContext ctx) {
        Validate.notNull(ctx, "Application Context cannot be null");
        this.ctx = ctx;
    }

    public boolean containsKey(Object key) {
        Validate.notNull(key, "Key cannot be null");
        return this.ctx.containsBean(key.toString());
    }

    public Object get(Object key) {
        Validate.notNull(key, "Key cannot be null");
        return this.ctx.getBean(key.toString());
    }

    public Set<String> keySet() {
        return new LinkedHashSet(Arrays.asList(this.ctx.getBeanDefinitionNames()));
    }

    public int size() {
        return this.ctx.getBeanDefinitionCount();
    }

    public boolean isEmpty() {
        return this.ctx.getBeanDefinitionCount() <= 0;
    }

    public boolean containsValue(Object value) {
        throw new UnsupportedOperationException("Method \"containsValue\" not supported in Beans object");
    }

    public Object put(String key, Object value) {
        throw new UnsupportedOperationException("Method \"put\" not supported in Beans object");
    }

    public void putAll(Map<? extends String, ?> m) {
        throw new UnsupportedOperationException("Method \"putAll\" not supported in Beans object");
    }

    public Object remove(Object key) {
        throw new UnsupportedOperationException("Method \"remove\" not supported in Beans object");
    }

    public void clear() {
        throw new UnsupportedOperationException("Method \"clear\" not supported in Beans object");
    }

    public Collection<Object> values() {
        throw new UnsupportedOperationException("Method \"values\" not supported in Beans object");
    }

    public Set<Entry<String, Object>> entrySet() {
        throw new UnsupportedOperationException("Method \"entrySet\" not supported in Beans object");
    }

}

这样就能用了。

猜你喜欢

转载自blog.csdn.net/WilsonSong1024/article/details/81535860
今日推荐