1. 程式人生 > >spring boot 中使用 Redis 與 Log

spring boot 中使用 Redis 與 Log

getclass spa databind amp cto ria statement database 英文

spring boot + mybatis + redis 配置

1.application.yml

#配置訪問的URL
server: servlet
-path: /web port: 8090 spring: datasource: druid: # 數據庫訪問配置, 使用druid數據源 db-type: com.alibaba.druid.pool.DruidDataSource #driver-class-name: oracle.jdbc.driver.OracleDriver #url: jdbc:oracle:thin:@localhost:
1521:ORCL driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/spring?useSSL=false username: root password: 123456 # 連接池配置 initial-size: 5 min-idle: 5 max-active: 20 # 連接等待超時時間 max-wait: 30000 # 配置檢測可以關閉的空閑連接間隔時間 time
-between-eviction-runs-millis: 60000 # 配置連接在池中的最小生存時間 min-evictable-idle-time-millis: 300000 validation-query: select 1 from dual test-while-idle: true test-on-borrow: false test-on-return: false # 打開PSCache,並且指定每個連接上PSCache的大小 pool-prepared-statements: true max
-open-prepared-statements: 20 max-pool-prepared-statement-per-connection-size: 20 # 配置監控統計攔截的filters, 去掉後監控界面sql無法統計, wall用於防火墻 filters: stat,wall
    #reids 必須使用代理才可以使用,此處配置必須,否則無法使用 # Spring監控AOP切入點,如x.y.z.service.
*,配置多個英文逗號分隔 aop-patterns: com.springboot.service.* # WebStatFilter配置 web-stat-filter: enabled: true # 添加過濾規則 url-pattern: /* # 忽略過濾的格式 exclusions: ‘*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*‘ # StatViewServlet配置 stat-view-servlet: enabled: true # 訪問路徑為/druid時,跳轉到StatViewServlet url-pattern: /druid/* # 是否能夠重置數據 reset-enable: false # 需要賬號密碼才能訪問控制臺 login-username: druid login-password: druid123 # IP白名單 # allow: 127.0.0.1 # IP黑名單(共同存在時,deny優先於allow) # deny: 192.168.1.218 # 配置StatFilter filter: stat: log-slow-sql: true redis: # Redis數據庫索引(默認為0) database: 0 # Redis服務器地址 host: 127.0.0.1 # Redis服務器連接端口 port: 6379 pool: # 連接池最大連接數(使用負值表示沒有限制) max-active: 8 # 連接池最大阻塞等待時間(使用負值表示沒有限制) max-wait: -1 # 連接池中的最大空閑連接 max-idle: 8 # 連接池中的最小空閑連接 min-idle: 0 # 連接超時時間(毫秒) timeout: 5000 #配置顯示執行sql的語句 logging: level: com: springboot: mapper: debug

2. RedisConfig 配置

package com.springboot.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    // 自定義緩存key生成策略
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, java.lang.reflect.Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    // 緩存管理器
    @Bean
    public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // 設置緩存過期時間
        cacheManager.setDefaultExpiration(10000);
        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template);// 設置序列化工具
        template.afterPropertiesSet();
        return template;
    }

    private void setSerializer(StringRedisTemplate template) {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }
}

spring boot + Log

1.LogAspect 配置

package com.springboot.aspect;

import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import com.springboot.annotation.Log;
import com.springboot.dao.SysLogDao;
import com.springboot.domain.SysLog;
import com.springboot.util.HttpContextUtils;
import com.springboot.util.IPUtils;

@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogDao sysLogDao;

    @Pointcut("@annotation(com.springboot.annotation.Log)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint point) {
        long beginTime = System.currentTimeMillis();
        try {
            // 執行方法
            point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        // 執行時長(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 保存日誌
        saveLog(point, time);
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        Log logAnnotation = method.getAnnotation(Log.class);
        if (logAnnotation != null) {
            // 註解上的描述
            sysLog.setOperation(logAnnotation.value());
        }
        // 請求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        // 請求的方法參數值
        Object[] args = joinPoint.getArgs();
        // 請求的方法參數名稱
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i++) {
                params += "  " + paramNames[i] + ": " + args[i];
            }
            sysLog.setParams(params);
        }
        // 獲取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 設置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));
        // 模擬一個用戶名
        sysLog.setUsername("mrbird");
        sysLog.setTime((int) time);
        Date date = new Date();
        sysLog.setCreateTime(date);
        // 保存系統日誌
        sysLogDao.saveSysLog(sysLog);
    }
}

2.日誌工具類 IPUtils 獲取 IP

package com.springboot.util;

import javax.servlet.http.HttpServletRequest;

public class IPUtils {

    /**
     * 獲取IP地址
     * 
     * 使用Nginx等反向代理軟件, 則不能通過request.getRemoteAddr()獲取IP地址
     * 如果使用了多級反向代理的話,X-Forwarded-For的值並不止一個,而是一串IP地址,X-Forwarded-For中第一個非unknown的有效IP字符串,則為真實IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {

        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

}

3.工具類 HttpContextUtils

package com.springboot.util;

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class HttpContextUtils {
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}

spring boot 中使用 Redis 與 Log