在一段时间内从事不同的工作时,我遇到了一些当时无法找到的实用程序的需求。 我看到我一次又一次地需要它们。 因此,我编写了自己的小型图书馆,发现它非常有用。 因此,我只是将其发布为开源Java库。
这是Github链接在线Javadoc可在此处获得另外,该库在Maven Central上可用。 这是Maven工件(在撰写本文时,最新版本为1.5.0.8,但将来可能会更改。要检查最新版本,请在
http://search.maven中搜索工件“ MgntUtils”
。 org / ):
<dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>javadoc</classifier> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>sources</classifier> </dependency>
以下只是其中的简短说明。 该库随附了写得很好(希望如此)的JavaDoc,并提供了详细的描述。 因此,这里是功能列表:
Stacktrace噪声滤波器
以我的经验,此功能对我来说是最通用和有用的。 当调试或尝试找出应用程序出了什么问题时,Stacktrace是一个救生器。 但是,在服务器端使用日志时,您会遇到巨大的stacktrace,其中包含各种框架和与Application Server相关的软件包中最长的无用的尾巴。 在这堆中的某处,有几条相关的迹线,它们可能位于无用的信息所分隔的不同段中。 寻找相关内容成为噩梦。 这是一个使用实际示例(不是为胆小的人)描述相同问题的链接
https://dzone.com/articles/filtering-stack-trace-hell 。 因此,在我的库中,有一个名为
TextUtils的类,它具有带有多个重载签名的
getStacktrace()方法。 它采用Throwable实例,并允许设置相关软件包的软件包前缀。
同样,相同的实用程序(从1.5.0.3版开始)具有方法
getStacktrace() ,该方法采用CharSequence接口而不是Throwable,因此可以像从Throwable提取的stacktrace一样过滤和缩短作为字符串存储的stacktrace。 因此,基本上可以在运行时或稍后从任何文本源(例如日志)中“动态”过滤堆栈跟踪。 (请澄清一下-该实用程序不支持解析和修改整个日志文件。它仅支持过滤作为String传递的stacktrace。因此,如果有人想过滤日志文件中的异常,则他们必须解析日志文件。并将stacktrace提取为单独的字符串,然后可以使用此实用程序过滤每个单独的stacktrace)。
这是一个用法示例。 假设您的公司代码始终位于以“ com.plain。*”开头的软件包中,因此您可以设置这样的前缀并执行此操作
logger.info(TextUtils.getStacktrace(e,true,"com.plain."));
这将非常巧妙地过滤掉跟踪中所有无用的部分,从而为您提供非常简洁的stacktrace。 另外,我发现预先设置前缀然后使用便捷方法非常方便
TextUtils.getStacktrace(e);
它将执行相同的操作。 预设前缀只需使用方法
setRelevantPackage("com.plain.");
如果要通过配置来预先设置此值,
则从库版本1.1.0.1开始,可以将环境变量“
MGNT_RELEVANT_PACKAGE ”或系统属性“
mgnt.relevant.package ”设置为值“
com.plain”。将被设置为该值,而无需调用方法
TextUtils.setRelevantPackage(“ com.plain。”); 明确地在您的代码中。 请注意,如果同时设置了系统属性值,则该属性值将优先于环境变量。 提醒一下,使用System属性,可以使用-D标志将其添加到命令行中:
“ -Dmgnt.relevant.package = com.plain。”
另外,如果您使用的库版本早于1.1.0.1,或者不想使用上述环境变量或系统属性,而您正在使用Spring环境,则可以通过在Spring配置中添加以下段来预设前缀:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass" value="com.mgnt.utils.TextUtils"/> <property name="targetMethod" value="setRelevantPackage"/> <property name="arguments" value="com.plain."/> </bean>
Javadoc详细解释了所有内容。 但是这里有一个小提示:您将获得以下堆栈跟踪:
at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() ... at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() ... at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks()
代替
at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed() at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() at sun.reflect.NativeMethodAccessorImpl.invoke() at sun.reflect.DelegatingMethodAccessorImpl.invoke() at java.lang.reflect.Method.invoke() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod() at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.transaction.interceptor.TransactionInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept() at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks()
静默字符串解析为整数,长整数等
相同的类
TextUtils提供了一些方法来静默地将String解析为Double,Long,Integer,Short和Byte类型(无任何异常)。 这些方法称为
parseStringToLong() parseStringToInteger()等。 他们都接受4个论点:
- 要解析的字符串
- 如果发生任何解析问题,则将Number(双精度,长整数,整数,短整数或字节)的实现用作默认值
- 如果第一个参数为null(可以为null,则不打印错误),则将作为错误消息输出到日志中的String
- 如果发生NumberFormatException,则将作为错误消息打印的字符串(可以为null,然后不打印错误)
解析字符串到时间间隔
在同一类
TextUtils中 ,有一个方法
parseStringToTimeInterval(字符串值) 。 此方法解析预期包含某个时间间隔值的字符串-一个带有可选时间单位后缀的数字值。 例如,字符串“ 38s”将解析为38秒,“ 24m”-24分钟“ 4h”-4小时,“ 3d”-3天,“ 45”解析为45毫秒。 支持的后缀是“
s ”表示秒,“
m ”表示分钟,“
h ”表示小时,“
d ”表示天。 不带后缀的字符串被认为拥有以毫秒为单位的值。 后缀不区分大小写。 如果提供的String包含不受支持的后缀,或者具有负数字值或零,或者具有非数字值-则抛出IllegalArgumentException。 此方法返回TimeInterval类-该库中也定义了一个类。 本质上,它具有两个具有相关getter和setter的属性:long“值”和java.util.concurrent.TimeUnit。 但是除了getter和setter之外,此类还具有
toMillis() ,
toSeconds() ,
toMinutes() ,
toHours()到 Days()的方法 。 这些方法在指定的时间范围内返回long值(与类
java.util.concurrent.TimeUnit中的相应方法相同)
此方法对于解析时间间隔属性(例如超时或来自配置文件的等待时间)可能非常有用。 它消除了从不同时间范围到来回毫秒之间不必要的计算。 考虑您有一个
methodInvokingInterval属性,需要设置5天。 因此,要设置毫秒值,您需要计算5天为432000000毫秒(显然这不是不可能完成的任务,但很烦人且容易出错),然后看到432000000值的其他任何人都必须将其计算回5令人沮丧的日子。 但是使用此方法,您会将属性值设置为“ 5d”并调用代码
long milliseconds = TextUtils.parsingStringToTimeInterval("5d").toMillis();
将解决您的转换问题。 显然,这不是一个过于复杂的功能,但是它可以在您的配置文件中增加简洁性和清晰度,并将一些挫败感和“愚蠢”的错误计算结果保存为毫秒级错误。
比较版本
此实用程序允许将String转换为版本,反之亦然,并正确比较版本和版本范围。 通常,如果您需要比较版本,则只需比较字符串。 因此,可以说版本“ 1.5.3”将大于版本“ 1.3.1”。 但是,如果您比较字符串“ 1.4.2”和“ 1.12.3”,则字符串“ 1.4.2”将错误地更大。 因此,该实用程序可以解决此类问题,此外,它还引入了VersionRange类,并允许对版本范围进行操作。 (请参阅类
TextUtils和类
VersionRange中的方法
compareVersions )
字符串Unicode转换器
类
StringUnicodeEncoderDecoder具有可以将String(以任何语言)转换为Unicode字符序列的方法,反之亦然。 例如,字符串“ Hello World”将转换为
“ \ u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064”
并可以恢复原状。
生命周期管理(自实例工厂)
此功能是一个软件包,其中包含一些小型基础结构,这些基础结构可简化和自动化与提供接口具体实现的工厂的工作。 该软件包仅包含2个类:
BaseEntityFactory和
BaseEntity 。 简而言之,此基础结构所做的是,如果创建一个扩展
BaseEntityFactory的工厂和一些接口,并扩展其所有具体实现的接口扩展
BaseEntity,则每个具体实现类类实例将自动插入到您的工厂中。 您无需担心如何以及何时填充工厂。 调用具体实现类的构造函数时,基础结构将为您完成此操作。 因此,您要做的就是创建任意数量的具体实现类,并确保为每个构造函数都调用一次。 之后,您可以使用工厂在代码中的任何位置获取任何具体的实现类。 这是一个简短的解释。 还有更多细节,但没有那么多。 有关此软件包的详细说明,请参阅
com.mgnt.lifecycle.management软件包的Javadoc API。 另外,源代码包含com.mgnt.lifecycle.management.example软件包,其中包含有关如何使用此功能的注释清楚且详细的代码示例。
至于实际用法,我发现它对于Spring框架非常有用。 请记住,Spring在初始化期间会实例化所有它定义的bean。 因此,在Spring上下文中,如果我们简单地将具体实现声明为Spring Bean,Spring将为我们实例化它们,从而自动初始化其工厂。 这可能非常方便。 想象一下,您有一些具有用户定义接口类型的属性的Bean,该属性具有多个实现,但是实际需要哪种实现是在运行时确定的。 因此,那时,您可以使用Factory的
getInstance(java.lang.String)方法访问所需的实现。 这将使您不必将所有具体的实例都注入到bean中,并且您将不必使用Spring
Bean Factory访问Spring定义的bean,因为这会违反Spring的非介入性(这意味着您可以编写不依赖于Spring的组件)春天)。 另外,如果在以后的某个阶段需要添加更多具体的实现,那么您要做的就是将实现类添加到代码中,并将它们声明为Spring Bean。 其余的工作将在Spring和此基础架构中完成!
文件工具
使用此实用程序,可以在指定或不指定字符集的情况下将文件读取为字符串,或者仅将其读取为字节数组。 该实用程序使用nio程序包和缓冲区来提高性能。 该实用程序的最大文件大小为2G。
时间效用
这只是一个便捷方法,它提供与Thread.sleep()相同的功能,但它是无声的。 即它“吞下” IterruptedException。 另外,它需要两个参数:睡眠时间和度量单位。 所以代替
try { Thread.sleep(2000); } catch (InterruptedException ie) { }
您可以这样写:
TimeUtils.sleepFor(2, TimeUnit.SECONDS);
我以为很可爱
就是这样。 随意下载该库。 它带有MIT许可证-我所知道的最宽松的许可证之一。 上面的链接提供了源代码,Javadoc和二进制版本。 该代码由JDK 8编译,但是其中没有版本8的功能。 它绝对应该与Java 7一起使用,我怀疑它可以与Java 6甚至5一起使用,但是还没有在那些版本上进行过测试。 可以随意使用它,如果喜欢的话,告诉其他人,如果有任何反馈,请随时给我发邮件michael_gantman@yahoo.com。