因為造輪子,我一個月就轉(zhuǎn)正了
往期熱門文章:
1、用了Stream后,代碼反而越寫越丑? 2、一不小心節(jié)約了 591 臺機器! 3、你見過哪些目瞪口呆的 Java 代碼技巧? 4、笑死!程序員延壽指南開源了 5、互聯(lián)網(wǎng)黑話,被上海人翻譯火了
作者 |?Baldwin_KeepMind
責(zé)編 | 伍杏玲
出品 | CSDN博客




public?interface?Constants?{
????//等下要引入的配置文件名
????String?CONFIG_FILE_NAME?=?"yzlogconfig";
????//配置文件中配置的日志路徑
????String?CONFIG_LOG_PATH?=?"logpath";
????//配置文件中配置的要掃描的,可能存在我們注解的路徑
????String?CONFIG_SACN_PATH?=?"scanpath";
????//若未聲明某些信息,則使用以下默認值
????//默認的我們的日志信息前綴,對日志信息做簡單描述
????String?DEFAULT_CONTENT_PREFIX?=?"注入值:";
????//默認的日志文件名(實際寫入時會在日志文件名后加上日期標簽)
????String?DEFAULT_FILE_NAME?=?"log";
????//日志信息類型,處理消息時會用到
????String?MSG_TYPE_LOG?=?"log";
????//默認的Linux系統(tǒng)下的日志路徑
????String?LINUX_LOG_PATH?=?"/home/data/";
????//默認的Windows系統(tǒng)下的日志路徑
????String?WIN_LOG_PATH?=?"D:/winLog/data/";
}
import?java.util.ResourceBundle;
public?class?ConfigurationUtil?{
????private?static?Object?lock?=?new?Object();
????private?static?ConfigurationUtil?config?=?null;
????private?static?ResourceBundle?rb?=?null;
????private?ConfigurationUtil(String?filename)?{
????????rb?=?ResourceBundle.getBundle(filename);
????}
????public?static?ConfigurationUtil?getInstance(String?filename)?{
????????synchronized?(lock)?{
????????????if?(null?==?config)?{
????????????????config?=?new?ConfigurationUtil(filename);
????????????}
????????}
????????return?(config);
????}
????public?String?getValue(String?key)?{
????????String?ret?=?"";
????????if?(rb.containsKey(key))?{
????????????ret?=?rb.getString(key);
????????}
????????return?ret;
????}
}
import?java.text.SimpleDateFormat;
import?java.util.Date;
public?class?DateUtil?{
????public?final?static?String?DATE_A?=?"yyyy-MM-dd";
????public?final?static?String?DATE_B?=?"yyyy-MM-dd?HH:mm:ss";
????public?final?static?String?DATE_C?=?"yyyyMMddHHmmss";
????public?final?static?String?DATE_D?=?"yyyyMMdd-HHmmss-SS";
????public?final?static?String?DATE_E?=?"M月d日";
????public?final?static?String?DATE_F?=?"MM-dd";
????public?final?static?String?DATE_G?=?"yyyyMMddHHmmss";
????//?普通的當前時間轉(zhuǎn)字符串方法,格式為yyyy-MM-dd
????public?static?String?getDate()?{
????????SimpleDateFormat?sdf?=?new?SimpleDateFormat(DATE_A);
????????return?sdf.format(new?Date());
????}
????public?static?String?getDateTime()?{
????????Date?date?=?new?Date();
????????String?datestr;
????????SimpleDateFormat?sdf?=?new?SimpleDateFormat(DATE_B);
????????datestr?=?sdf.format(date);
????????return?datestr;
????}
}
/**
?*@描述?用于判斷當前系統(tǒng)
?*@參數(shù)
?*@返回值
?*@創(chuàng)建人??Baldwin
?*@創(chuàng)建時間??2020/4/4
?*@修改人和其它信息
?*/
public?class?SystemUtil?{
????/**
?????*?判斷系統(tǒng)時win還是linux
?????*?@return
?????*/
????public?static?boolean?isLinux(){
????????String?name?=?System.getProperty("os.name");
????????if(name.toLowerCase().startsWith("win"))
????????????return?false;
????????else
????????????return?true;
????}
}
import?java.io.BufferedWriter;
import?java.io.File;
import?java.io.FileOutputStream;
import?java.io.OutputStreamWriter;
public?class?FileUtil?{
????//?在已經(jīng)存在的文件后面追加寫的方式
????public?static?boolean?write(String?path,?String?str)?{
????????File?f?=?new?File(path);
????????File?fileParent?=?f.getParentFile();
????????BufferedWriter?bw?=?null;
????????try?{
????????????if(!fileParent.exists()){
????????????????fileParent.mkdirs();
????????????}
????????????if(!f.exists()){
????????????????f.createNewFile();
????????????}
????????????//?new?FileWriter(name,true)設(shè)置文件為在尾部添加模式,參數(shù)為false和沒有參數(shù)都代表覆寫方式
????????????bw?=?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream(path,?true),?"UTF-8"));
????????????bw.write(str);
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????????return?false;
????????}?finally?{
????????????try?{
????????????????if(bw!=null)bw.close();
????????????}?catch?(Exception?e)?{
????????????????System.out.println("FileUtil.write?colse?bw?wrong:"?+?e);
????????????}
????????}
????????return?true;
????}
}
import?cn.yzstu.support.Constants;
import?cn.yzstu.support.DateUtil;
import?cn.yzstu.support.FileUtil;
import?cn.yzstu.support.SystemUtil;
public?class?LogUtil?{
????//日志寫入操作
????public?static?void?write2file(String?path,?String?fileName,?String?content)?{
????????//獲取當前日期,我們的日志保存的文件夾名是自定義path+日期
????????String?date?=?DateUtil.getDate()+"/";
????????try?{
????????????//傳了path,那我們直接用這個path
????????????if?(null?!=?path?&&?0?!=?path.length())?{
????????????????//寫入
????????????????FileUtil.write(path?+?date?+?fileName?+?".txt",
????????????????????????DateUtil.getDateTime()?+?":"?+?content?+?"\r\n");
????????????}?else?{
????????????????//沒有傳path或錯誤使用默認的路徑
????????????????if?(SystemUtil.isLinux())?{
????????????????????FileUtil.write(Constants.LINUX_LOG_PATH?+?date?+?fileName?+?".txt",
????????????????????????????DateUtil.getDateTime()?+?":"?+?content?+?"\r\n");
????????????????}?else?{
????????????????????FileUtil.write(Constants.WIN_LOG_PATH?+?date?+?fileName?+?".txt",
????????????????????????????DateUtil.getDateTime()?+?":"?+?content?+?"\r\n");
????????????????}
????????????}
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????}
}
import?cn.yzstu.core.MsgQueue;
import?cn.yzstu.support.Constants;
public?class?LogMsg?{
????private?String?path;
????private?String?content;
????private?String?fileName;
????private?String?msgType;
????public?LogMsg(String?path,?String?content,?String?fileName)?{
????????this.path?=?path;
????????this.content?=?content;
????????this.fileName?=?fileName;
????????this.msgType?=?"logmsg";
????????//在構(gòu)造函數(shù)中就讓這個消息入列
????????MsgQueue.push(this);
????}?
????public?String?getPath()?{
????????return?path;
????}
????public?void?setPath(String?path)?{
????????this.path?=?path;
????}
????public?String?getContent()?{
????????return?content;
????}
????public?void?setContent(String?content)?{
????????this.content?=?content;
????}
????public?String?getFileName()?{
????????return?fileName;
????}
????public?void?setFileName(String?fileName)?{
????????this.fileName?=?fileName;
????}
????public?String?getMsgType()?{
????????return?this.msgType;
????}
????public?void?setMsgType(String?msgType)?{
????????this.msgType?=?msgType;
????}
????@Override
????public?String?toString()?{
????????return?"LogMsg{"?+
????????????????"path='"?+?path?+?'\''?+
????????????????",?content='"?+?content?+?'\''?+
????????????????",?fileName='"?+?fileName?+?'\''?+
????????????????",?msgType='"?+?msgType?+?'\''?+
????????????????'}';
????}
}
import?cn.yzstu.beans.LogMsg;
import?java.util.Queue;
import?java.util.concurrent.ConcurrentLinkedDeque;
public?class?MsgQueue?{
????private?static?Queue?queue?=?new?ConcurrentLinkedDeque<>();
????//消息入列
????public?static?boolean?push(LogMsg?logMsg){
????????return?queue.offer(logMsg);
????}
????//消息出列
????public?static?LogMsg?poll(){
????????return?queue.poll();
????}
????//消息隊列是否已經(jīng)處理完畢,處理完畢返回true
????public?static?boolean?isFinash(){
????????return?!queue.isEmpty();
????}
}
import?java.lang.annotation.*;
//作用于字段
@Target({ElementType.FIELD})
//運行時生效
@Retention(RetentionPolicy.RUNTIME)
@Documented
public?@interface?YzLogWrite?{
????//需要注解的值
????int?value()?default?-1;
????//默認是Linux系統(tǒng),默認記錄文件夾如下
????String?path()?default?"";
????//文件名
????String?fileName()?default?"";
????//內(nèi)容
????String?msgPrefix()?default?"";
}
import?cn.yzstu.annotation.YzLogWrite;
import?cn.yzstu.beans.LogMsg;
import?cn.yzstu.support.Constants;
import?java.io.File;
import?java.lang.annotation.Annotation;
import?java.lang.reflect.Field;
import?java.net.URL;
import?java.util.ArrayList;
import?java.util.List;
public?class?DealAnnotation?{
????//配置文件中設(shè)置的log所在地址
????private?static?String?LOG_PATH?=?ConfigurationUtil.getInstance(Constants.CONFIG_FILE_NAME).getValue(Constants.CONFIG_LOG_PATH);
????//保存那些存在注解的class的類名
????private?List<String>?registyClasses?=?new?ArrayList<>();
????public?void?injectAndMakeMsg()?{
????????//需要掃描的注解可能存在的位置
????????String?scanPath?=?ConfigurationUtil.getInstance(Constants.CONFIG_FILE_NAME).getValue(Constants.CONFIG_SACN_PATH);
????????doScanner(scanPath);
????????for?(String?className?:?registyClasses)?{
????????????try?{
????????????????Class?clazz?=?Class.forName(className);
????????????????Field[]?fields?=?clazz.getDeclaredFields();
????????????????for?(Field?field?:?fields)?{
????????????????????//獲取類的所有注解
????????????????????Annotation[]?annotations?=?field.getAnnotations();
????????????????????//沒有注解或沒有我們的注解,跳過
????????????????????if?(0?==?annotations.length?||?!field.isAnnotationPresent(YzLogWrite.class))?{
????????????????????????continue;
????????????????????}
????????????????????//獲取注解
????????????????????YzLogWrite?yzLogWrite?=?field.getAnnotation(YzLogWrite.class);
????????????????????//提取注解中的值
????????????????????//聲明大于配置
????????????????????String?path?=?null?==?yzLogWrite.path()?||?yzLogWrite.path().isEmpty()???LOG_PATH?:?yzLogWrite.path();
????????????????????String?content?=?null?==?yzLogWrite.msgPrefix()?||?yzLogWrite.msgPrefix().isEmpty()???Constants.DEFAULT_CONTENT_PREFIX?:?yzLogWrite.msgPrefix();
????????????????????String?fileName?=?null?==?yzLogWrite.fileName()?||?yzLogWrite.fileName().isEmpty()???Constants.DEFAULT_FILE_NAME?:?yzLogWrite.fileName();
????????????????????int?value?=?yzLogWrite.value();
????????????????????//新建logMsg,在構(gòu)造函數(shù)中已入列
????????????????????new?LogMsg(path,?content?+?":"?+?value,?fileName);
????????????????????//開始注入
????????????????????//強制訪問該成員變量
????????????????????field.setAccessible(true);
????????????????????//注入int值
????????????????????field.setInt(Integer.class,?value);
????????????????}
????????????}?catch?(ClassNotFoundException?|?IllegalAccessException?e)?{
????????????????e.printStackTrace();
????????????}
????????}
????}
????private?void?doScanner(String?scanPath)?{
????????URL?url?=?this.getClass().getClassLoader().getResource(scanPath.replaceAll("\\.",?"/"));
????????File?classPath?=?new?File(url.getFile());
????????for?(File?file?:?classPath.listFiles())?{
????????????if?(file.isDirectory())?{
????????????????//如果是目錄則遞歸調(diào)用,直到找到class
????????????????doScanner(scanPath?+?"."?+?file.getName());
????????????}?else?{
????????????????if?(!file.getName().endsWith(".class"))?{
????????????????????continue;
????????????????}
????????????????String?className?=?(scanPath.replace("/",?".")?+?"."?+?file.getName().replace(".class",?""));
????????????????registyClasses.add(className);
????????????}
????????}
????}
}
import?cn.yzstu.beans.LogMsg;
public?class?DealMsg?extends?Thread{
????@Override
????public?void?run()?{
????????while?(MsgQueue.isFinash()){
????????????//多態(tài)
????????????//實際中,我們可以定義很多中msg,用type來區(qū)分,并通過不同的方法來處理
????????????//此處運用了這種思想,但是沒有實現(xiàn)具體操作
????????????LogMsg?logMsg?=?MsgQueue.poll();
????????????switch?(logMsg.getMsgType()){
????????????????case?"logmsg"?:
????????????????????//如果類型是logmsg,那就通過日志來處理
????????????????????dealLogMsg(logMsg);
????????????????????break;
????????????????default:defaultMethod(logMsg);
????????????}
????????}
????????this.interrupt();
????}
????private?void?defaultMethod(LogMsg?logMsg)?{
????????System.out.println("no?msg");
????}
????private?void?dealLogMsg(LogMsg?logMsg)?{
? ? ? ?LogUtil.write2file(logMsg.getPath(),logMsg.getFileName(),logMsg.getContent());
????}
????@Override
????public?synchronized?void?start()?{
????????this.run();
????}
}
import?cn.yzstu.annotation.YzLogWrite;
public?class?StartWork?{
????//程序入口
????public?static?void?doWork(){
????????//處理:掃描注解、注入、發(fā)送日志消息到隊列
????????new?DealAnnotation().injectAndMakeMsg();
????????//創(chuàng)建線程來處理消息
????????new?DealMsg().start();
????}
}

#logpath最后需要帶/
logpath?=?/opt/
scanpath?=?cn/yzstu/tt
import?cn.yzstu.annotation.YzLogWrite;
import?cn.yzstu.core.StartWork;
public?class?Demo?{
????//因為測試用的main函數(shù)是static,所以此時將age設(shè)置為static
????@YzLogWrite(value?=?18,msgPrefix?=?"記錄Baldwin的年齡:")
????static?int?age;
????public?static?void?main(String[]?args)?{
????????StartWork.doWork();
????????System.out.println(age);
????}
}
/opt/java/jdk1.8.0_241/bin/java?-javaagent:/opt/jetbrains/idea-IU-193.6911.18/lib/idea_rt.jar=38115:/opt/jetbrains/idea-IU-193.6911.18/bin?-Dfile.encoding=UTF-8?-classpath?/opt/java/jdk1.8.0_241/jre/lib/charsets.jar:/opt/java/jdk1.8.0_241/jre/lib/deploy.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/cldrdata.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/dnsns.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/jaccess.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/jfxrt.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/localedata.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/nashorn.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/sunec.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/sunjce_provider.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/sunpkcs11.jar:/opt/java/jdk1.8.0_241/jre/lib/ext/zipfs.jar:/opt/java/jdk1.8.0_241/jre/lib/javaws.jar:/opt/java/jdk1.8.0_241/jre/lib/jce.jar:/opt/java/jdk1.8.0_241/jre/lib/jfr.jar:/opt/java/jdk1.8.0_241/jre/lib/jfxswt.jar:/opt/java/jdk1.8.0_241/jre/lib/jsse.jar:/opt/java/jdk1.8.0_241/jre/lib/management-agent.jar:/opt/java/jdk1.8.0_241/jre/lib/plugin.jar:/opt/java/jdk1.8.0_241/jre/lib/resources.jar:/opt/java/jdk1.8.0_241/jre/lib/rt.jar:/root/IdeaProjects/LogUtil/target/classes?cn.yzstu.tt.Demo
18
Process?finished?with?exit?code?0

2020-04-06 00:17:30:記錄Baldwin的年齡::18

往期熱門文章:
1、笑死!程序員延壽指南開源了 2、用 Dubbo 傳輸文件?被老板一頓揍! 3、45 個 Git 經(jīng)典操作場景,專治不會合代碼! 4、@Transactional 注解失效的3種原因及解決辦法 5、小學(xué)生們在B站講算法,網(wǎng)友:我只會阿巴阿巴 6、Spring爆出比Log4j2還大的漏洞? 7、Objects.equals 有坑!!! 8、Redis 官方可視化工具,功能真心強大! 8、xxl-job 和 ElasticJob比,誰牛? 10、推薦好用的 Spring Boot 內(nèi)置工具類
評論
圖片
表情
