Spring加载顺序典例

Spring加载顺序典例

需求背景

借用log4j2,向数据库中新增一条记录,对于特殊的字段需要借助线程的环境变量。其中某个字段需要在数据库中查询到具体信息后插入,在借助Spring MVC的Dao层时遇到了加载顺序问题。

解决方案

log4j2插入数据库的方案参考文章:

<Column name="user_info" pattern="%X{user_info}" isUnicode="false" />

需要执行日志插入操作(比如绑定到一个级别为insert、logger.insert())的线程中有环境变量user_info。

解决环境变量的方法:
拦截器:

@Component
public class LogInterceptor implements HandlerInterceptor {
    
    

    /**
     * 需要记录在log中的参数
     */
    public static final String USER_INFO= "user_info";

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object arg)
        throws Exception {
    
    
        String userName = LoginContext.getCurrentUsername();
        ThreadContext.put(USER_INFO, getUserInfo());
    }
    
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
        Object arg, Exception exception) throws Exception {
    
    
        ThreadContext.remove(USER_INFO);
    }

需要拦截的URL配置:

@Configuration
public class LogConfigurer implements WebMvcConfigurer {
    
    
    String[] logUrl = new String[] {
    
    
        "/**",
    };

    String[] excludeUrl = new String[] {
    
    
        "/**/*.js", "/**/*.css", "/**/*.jpg", "/**/*.png", "/**/*.svg", "/**/*.woff", "/**/*.eot", "/**/*.ttf",
        "/**/*.less", "/favicon.ico", "/license/lackofresource", "/error"
    };

    /**
     * 注册一个拦截器
     *
     * @return HpcLogInterceptor
     */
    @Bean
    public LogInterceptor setLogBean() {
    
    
        return new LogInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry reg) {
    
    
        // 拦截的对象会进入这个类中进行判断
        InterceptorRegistration registration = reg.addInterceptor(setLogBean());
        // 添加要拦截的路径与不用拦截的路径
        registration.addPathPatterns(logUrl).excludePathPatterns(excludeUrl);
    }
}

如下待优化:

问题就出在如何获取信息这个步骤,原本的方案是:
通过Dao userDao从数据库查询信息,然后填充进去。
出现的问题是:userDao无法通过@Autowired方式注入。
原因:
调用处SpringBoot未完成初始化,导致dao层在调用时每次都是null。
因此最后采用的方式如下:

@Component
public class LogInterceptor implements HandlerInterceptor {
    
    

    /**
     * 需要记录在log中的参数
     */
    public static final String USER_INFO= "user_info";
	
	@Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object arg)
        throws Exception {
    
    
        String userName = LoginContext.getCurrentUsername();
        ThreadContext.put(USER_INFO, getUserInfo());
    }
    
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
        Object arg, Exception exception) throws Exception {
    
    
        ThreadContext.remove(USER_INFO);
    }

	public String getUserInfo(String userName) {
    
    
        String sqlTemplate = "select user_info from Test.test_user where user_name = ?";
        List<String> userInfo= new ArrayList<>();
        userInfo= jdbcTemplate.query(sqlTemplate, preparedStatement -> {
    
    
            preparedStatement.setString(1, userName);
        }, new SecurityRoleDtoMapper());

        if (userInfo.size() == 0) {
    
    
            return Constants.HPC_NORMAL_USER;
        }
        return userInfo.get(0);
    }

猜你喜欢

转载自blog.csdn.net/weixin_38370441/article/details/111077178