springboot+jpa+security+log4j(aop)+redis(aop)
阿新 • • 發佈:2018-11-09
本篇主要介紹spring boot 整合redis做資料快取,log4j做日誌,利用的是spring aop切面程式設計技術,利用註解標識切面。
springboot這裡不做介紹
一、首先引入pom.xml配置
<!-- springboot web support --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- spring web hot develop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <!-- springboot redis support --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- redis pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- thymeleaf engine --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- security thymeleaf lable --> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity4</artifactId> </dependency> <!-- security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- spring aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- oracle --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency> <!-- 阿里巴巴資料來源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <!-- mysql jdbc driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- jpa jar --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- properites --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
二、配置檔案我裡這用的是yml格式的,tab縮排,如果是properties格式的,請自行配置
spring:
redis:
database: 0
password:
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
timeout: 10000
三、redis註解
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Cacheable { static enum CacheableType{ GETORSAVE, UPDATE } /** * 快取key配置自動生成key * @return */ String key() default ""; /** * key取值與第幾個引數,預設第一個,配置自動設定key * @return */ CacheableType method() default CacheableType.GETORSAVE; /** * 失效時間毫秒 * 預設一分鐘失效 * @return */ int expireTime() default 60000; }
四、reidis aop切面
@Aspect @Component public class SpringCacheAop { @Autowired private RedisTemplate<String, Object> redisTemplate; @Around(value="@annotation(com.msw.spring.config.cache.Cacheable)") public Object Around(ProceedingJoinPoint poin){ Object value = null; //獲取註解類值 Cacheable anno = getAnnotation(poin, Cacheable.class); //獲取入參 String key = getKey(anno,poin); if(anno.method().equals(Cacheable.CacheableType.UPDATE)){ redisTemplate.delete(key); try { value = poin.proceed(); } catch (Throwable e1) { // TODO Auto-generated catch block e1.printStackTrace(); } redisTemplate.opsForValue().set(key, value, anno.expireTime(),TimeUnit.MILLISECONDS);; }else if(anno.method().equals(Cacheable.CacheableType.GETORSAVE)){ value = redisTemplate.opsForValue().get(key); if(value != null){ return value; } //獲取返回值 try { value = poin.proceed(); } catch (Throwable e1) { // TODO Auto-generated catch block e1.printStackTrace(); } redisTemplate.opsForValue().set(key, value, anno.expireTime(),TimeUnit.MILLISECONDS);; } return value; } /** * key生成策略 * @param anno * @param args * @return */ private String getKey(Cacheable anno, ProceedingJoinPoint poin) { String key = null; if(poin.getArgs().length > 0){ key = Arrays.toString(poin.getArgs()); }else{ key = poin.getSignature().getName(); } return DigestUtils.sha1DigestAsHex(key); } /** * * @Title: getAnnotation * @Description: 獲得Annotation物件 * @param @param <T> * @param @param jp * @param @param clazz * @param @return * @return T * @throws */ private <T extends Annotation> T getAnnotation(ProceedingJoinPoint jp,Class<T> clazz) { MethodSignature joinPointObject = (MethodSignature) jp.getSignature(); Method method = joinPointObject.getMethod(); return method.getAnnotation(clazz); } @SuppressWarnings("unused") private <T extends Annotation> List<T> getParameterAnnotations(ProceedingJoinPoint jp,Class<T> clazz){ MethodSignature joinPointObject = (MethodSignature) jp.getSignature(); Method method = joinPointObject.getMethod(); Annotation[][] annotations = method.getParameterAnnotations(); List<T> result = new ArrayList<T>(); for(Annotation[] anno:annotations){ for(Annotation a: anno){ Class<? extends Annotation> annotationType = a.annotationType(); T[] type = annotationType.getDeclaredAnnotationsByType(clazz); System.out.println(type); } } return result; } }
aop基於註解的快取已經配置成功了,如果需要快取的介面加上@Cacheable就可以實現快取了,可以在命令列redis-cli中看到。例如:
public interface UserDao extends JpaRepository<User, Integer>{
@Query("select u from User u where u.username=:username")
@Cacheable
User findByUserName(@Param("username")String username);
}
上面已經配置好了基於註解的快取,下面配置log4j日誌log,這個配置就比較簡單了。
@Aspect
@Component
public class SpringAopLog4j {
private final Log logger = LogFactory.getLog(getClass());
//這裡就是切入的包名方法
//如這裡就是切入controller包所有的類的所有方法
@Pointcut("execution(* com.msw.spring.controller.*.*(..))")
public void pointCut() {}
@Around(value="pointCut()")
public Object Around(ProceedingJoinPoint poin){
try {
return poin.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
@Before(value="pointCut()")
public void Before(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("#####################request###########################");
logger.info("URL: "+request.getRequestURI().toString());
logger.info("HTTP_METHOD:"+request.getMethod());
logger.info("IP:"+request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while(enu.hasMoreElements()) {
String name = (String)enu.nextElement();
logger.info(name+"="+request.getParameter(name));
}
}
@After(value="pointCut()")
public void After(JoinPoint joinPoint){
}
@AfterReturning(value="pointCut()",returning= "rec")
public void AfterReturning(JoinPoint joinPoint, Object rec){
logger.info("response:"+rec);
logger.info("#######################End#############################");
}
@AfterThrowing(value="pointCut()",throwing="ex")
public void AfterThrowing(JoinPoint joinPoint, Exception ex){
}
}
執行就可以看到每一個request都有顯示入參出參。
GitHub地址:https://github.com/yzliusha/springboot-security-redis-jpa-oracle-aop-Log4j-cache-