Java 中待总结工具类学习(自定义注解,读取配置,字面List)
1、使用 MessageFormat 格式化文本
int planet = 7; String event = "a disturbance in the Force"; String result = MessageFormat.format( "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", planet, new Date(), event);
The output is:
At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7.
2、自定义注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OperateLog { /** * 模块名称 * @return */ String moudleName() default ""; /** * 操作名称 * @return */ String optName() default ""; /** * 业务类型描述 * @return */ String description() default ""; }
通过 aop 做拦截处理
@Aspect @Component public class OperateLogAspect { @Autowired private OperateLogService operateLogService; @Pointcut("@annotation(com.youngcms.core.annotation.OperateLog)") public void operateLogCut(){ } @Around("operateLogCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); //执行方法 Object result = point.proceed(); //执行时长(毫秒) long time = System.currentTimeMillis() - beginTime; //保存日志 saveOperateLog(point, time); return result; } private void saveOperateLog(ProceedingJoinPoint joinPoint, long time) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); RequestMapping classRequestMapping=method.getDeclaringClass().getAnnotation(RequestMapping.class); OperateLog operateLog=method.getAnnotation(OperateLog.class); RequestMapping mothodRequestMapping= method.getAnnotation(RequestMapping.class); com.youngcms.bean.OperateLog operateLogBean=new com.youngcms.bean.OperateLog(); if(operateLog!=null){ operateLogBean.setModuleName(operateLog.moudleName()); operateLogBean.setOptName(operateLog.optName()); operateLogBean.setDescription(operateLog.description()); } //请求的类名 String className = joinPoint.getTarget().getClass().getName(); //请求的方法名 String methodName = signature.getName(); //请求的参数 //Object[] args = joinPoint.getArgs(); operateLogBean.setIp(IPUtils.getIpAddr(HttpKit.getRequest())); operateLogBean.setTime(time); operateLogBean.setMethod(className+"."+methodName+"()"); operateLogBean.setUrl(classRequestMapping.value()[0]+mothodRequestMapping.value()[0]); String username = ((SysUser) SecurityUtils.getSubject().getPrincipal()).getRealName(); operateLogBean.setAuthor(username); operateLogBean.setCreateTime(DateUtil.dateToStr(new Date(), 12)); operateLogService.insert(operateLogBean); } }
3、条件判断注解
ConditionalOnProperty 的意思是,当 usemysql.local 属性配置存在并且不为 false,则创建这个 bean
@Bean @ConditionalOnProperty( name = "usemysql", havingValue = "local") @ConditionalOnMissingBean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true"); dataSource.setUsername("mysqluser"); dataSource.setPassword("mysqlpass"); return dataSource; }
4.获取 ip 地址工具类
ublic class IPUtils { private static Logger logger = LoggerFactory.getLogger(IPUtils.class); /** * 获取IP地址 * * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = null; try { ip = request.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } catch (Exception e) { logger.error("IPUtils ERROR ", e); } return ip; } }
5.读取配置文件
// 获取 config/constant.properties 文件中的配置内容 private static ResourceBundle bundle = ResourceBundle.getBundle("config/constant"); public static String fileUploadPath =bundle.getString("file-upload.dir");
6.字面量形式构建 list
public class DefaultSqlInjector extends AbstractSqlInjector { @Override public List<AbstractMethod> getMethodList(Class<?> mapperClass) { return Stream.of( new Insert(), new Delete(), new DeleteByMap(), new DeleteById(), new DeleteBatchByIds(), new Update(), new UpdateById(), new SelectById(), new SelectBatchByIds(), new SelectByMap(), new SelectOne(), new SelectCount(), new SelectMaps(), new SelectMapsPage(), new SelectObjs(), new SelectList(), new SelectPage() ).collect(toList()); } }
7.版本序列化防止反序列化失败
实现序列化接口添加
private static final long serialVersionUID = 1L;
反序列化的时候,虚拟机同样会先读取该变量值,然后再当前读取的类中寻找同样的变量值,如果找到,那么反序列话成功,找不到即会报异常。
默认 serialVersionUID 由虚拟机计算,然而如果对象结构发生变化,该值也会变化,因此我们显示声明,虚拟机就不会再进行计算了,可以保证向后兼容性。
233