User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • Enamiĝu al vi
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • 666资源站
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
Help?

Please contact us on our email for need any support

Support
    首页   ›   Spring   ›   SpringBoot   ›   正文
SpringBoot

SpringBoot—logback日志配置

2020-07-06 01:16:44
1515  0 0

阅读完需:约 11 分钟

  1. spring boot可以适应所有日志框架,只需在类路径下包含相应的依赖来激活各种日志系统。
  2. spring boot底层使用slf4j + logback框架来实现日志记录,所以如果想要自定义logback配置,就无需添加相关依赖了(spring-booot-stater中已包含相关依赖)
  3. 在类路径下放置自定义日志配置文件(xml配置文件),spring boot就不会使用它本身的默认日志配置了
  4. logback中文文档——http://www.logback.cn/01%E7%AC%AC%E4%B8%80%E7%AB%A0logback%E4%BB%8B%E7%BB%8D.html

上图是spring boot官方文档的提示内容,意思是:根据您的日志记录系统,将加载相应的文件使用。即如果我们使用logback日志框架,那么可以使用logback-spring.xml、logback-spring.groovy、logback.xml、logback.groovy之一作为配置文件来加载。

自定义例子(1):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <!--配置控制台日志输出格式-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <!--%d表示日期, %msg表示日志的信息, %n表示换行-->
                %d - %msg%n
            </pattern>
        </layout>
    </appender>

    <!--配置info信息输出到一个文件-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--根据级别过滤掉匹配的日志,不输出error级别的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <!--匹配上ERROR级别的日志信息,则不会输出到该文件中-->
            <onMatch>DENY</onMatch>
            <!--匹配不上ERROR级别的日志信息,则输出到该文件中-->
            <onMismatch>ACCEPT</onMismatch>
            <!--这样过滤以后,该文件中只会输出info级别的日志信息-->
        </filter>
        <!--日志输出格式,同上-->
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>

        <!--滚动策略,按时间每天生成一个日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件路径-->
            <fileNamePattern>F:/log/springboot/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--配置error信息输出到一个文件-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--根据范围过滤日志,只输出error级别的日志-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <!--日志输出格式-->
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>

        <!--滚动策略,按时间每天生成一个日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件路径-->
            <fileNamePattern>F:/log/springboot/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>

自定义例子(2):

<?xml version="1.0" encoding="utf-8" ?>
<!--
1) 根节点<configuration>,包含下面三个属性:
    scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
    scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration scan="true" scanPeriod="60" debug="false">

    <!--控制台输出日志格式-->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss} -- %-5level -- [%thread] -- %logger{50} --- %msg %n}"/>
    <!--文件输出日志格式-->
    <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd hh:mm:ss} -- %-5level -- [%thread] -- %logger{50} --- %msg %n}"/>

    <!--
        Appender: 设置日志信息的去向,常用的有以下几个
           1) ch.qos.logback.core.ConsoleAppender (控制台)
           2) ch.qos.logback.core.rolling.RollingFileAppender (文件大小到达指定尺寸的时候产生一个新文件)
           3) ch.qos.logback.core.FileAppender (文件)
    -->

    <!--控制台配置-->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
         <!--当环境是dev开发环境时,这部分配置才生效-->
         <springProfile name="dev">
             <!--日志输出格式-->
             <encoder>
                 <pattern>${CONSOLE_LOG_PATTERN}</pattern>
             </encoder>
         </springProfile>
         <!--当环境不是dev开发环境时,这部分配置才生效-->
         <springProfile name="!dev">
             <!--日志输出格式-->
             <encoder>
                 <pattern>--%logger{50} --- %msg %n</pattern>
             </encoder>
         </springProfile>
    </appender>

    <!--日志记录文件配置-->
    <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--当环境是production生产环境时,这部分配置才生效
                即在production生产环境上,我们才将日志信息记录到日志文件中-->
        <springProfile name="production">
            <!--日志文件保存路径,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建 -->-->
            <file>D:\idea\logs\example-logging.log</file>
            <!--基于大小和时间的轮转策略,当日志内容超出文件大小限制后,会自动生成一个文件来继续记录和重命名-->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!--当日志内容超出文件大小限制后,会自动生成一个文件来继续记录,文件按下面格式命名-->
                <fileNamePattern>D:\idea\logs\example-logging-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
                <!--文件最大限制,默认10MB-->
                <maxFileSize>10MB</maxFileSize>
                <!--文件最大保存周期,默认7天-->
                <maxHistory>7</maxHistory>
                <!--所有归档文件总的大小限制-->
                <totalSizeCap>20GB</totalSizeCap>
            </rollingPolicy>
            <!--日志输出格式-->
            <encoder>
                <pattern>${FILE_LOG_PATTERN}</pattern>
            </encoder>
        </springProfile>
    </appender>

    <!--
        用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
        <logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性
        name:
            用来指定受此logger约束的某一个包或者具体的某一个类。
        level:
            用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
            如果未设置此属性,那么当前logger将会继承上级的级别。
        additivity:
            是否向上级logger传递打印信息。默认是true。
        <logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger
    -->
    <logger name="com.cd.example.one" level="trace"/>
    <logger name="com.cd.example.two" level="debug"/>
    <logger name="com.cd.example.three" level="warn"/>

    <!--
        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。
            <root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger
            使该指定的appender生效
    -->
    <root level="info">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
    </root>

</configuration>

关于这个日志的应用:

一般而言日志只要开启就可以了基本不需要自定义但是有时候要应用时就需要自定义配置,比如:vue+springboot实现控制台日志实时推送前台

1.自定义一个日志配置,目的是将日志转化自己进行处理。

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback-demo</contextName>

<!--    <!–输出到控制台 ConsoleAppender–>-->
<!--    <appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">-->
<!--        <!–展示格式 layout–>-->
<!--        <layout class="ch.qos.logback.classic.PatternLayout">-->
<!--            <pattern>%d -1 %msg%n</pattern>-->
<!--        </layout>-->
<!--    </appender>-->

    <!--输出到控制台 ConsoleAppender-->
    <appender name="consoleLog2" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!--encoder 默认配置为PatternLayoutEncoder-->
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="cn.vhrs.untils.LogFilter"> </filter>
    </appender>
    
    <!--指定最基础的日志输出级别-->
    <root level="info">
        <!--appender将会添加到这个loger-->
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="consoleLog2"/>
    </root>
</configuration>

2.进行日志的处理( 日志过滤器 )

@Service
public class LogFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        String exception = "";
        IThrowableProxy iThrowableProxy1 = event.getThrowableProxy();
        if(iThrowableProxy1!=null){
            exception = "<span class='excehtext'>"+iThrowableProxy1.getClassName()+" "+iThrowableProxy1.getMessage()+"</span></br>";
            for(int i=0; i<iThrowableProxy1.getStackTraceElementProxyArray().length;i++){
                exception += "<span class='excetext'>"+iThrowableProxy1.getStackTraceElementProxyArray()[i].toString()+"</span></br>";
            }
        }
        LoggerMessage loggerMessage = new LoggerMessage(
                event.getMessage()
                , DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())),
                event.getThreadName(),
                event.getLoggerName(),
                event.getLevel().levelStr,
                exception,
                ""
        );
        LoggerQueue.getInstance().push(loggerMessage);
        return FilterReply.ACCEPT;
    }
}

3. 创建一个阻塞队列,作为日志系统输出的日志的一个临时载体

public class LoggerQueue {
    //队列大小
    public static final int QUEUE_MAX_SIZE = 10000;
    private static LoggerQueue alarmMessageQueue = new LoggerQueue();
    //阻塞队列
    private BlockingQueue blockingQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE);

    private LoggerQueue() {
    }

    public static LoggerQueue getInstance() {
        return alarmMessageQueue;
    }

    /**
     * @Description: 消息入队
     * @Return: boolean
     * @Author: leijun
     * @Date: 2019/11/26
     **/
    public boolean push(LoggerMessage log) {
//        System.out.println("消息入队的信息===="+log);
        return this.blockingQueue.add(log);//队列满了就抛出异常,不阻塞
    }

    /**
     * @Description: 消息出队
     * @Return: com.unismc.springbootudcap.powersecurity.entity.LoggerMessage
     * @Author: leijun
     * @Date: 2019/11/26
     **/
    public LoggerMessage poll() {
        LoggerMessage result = null;
        try {
//            System.out.println("输出:"+this.blockingQueue);
            result = (LoggerMessage) this.blockingQueue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }
}

4. 创建一个日志实体

/**
 * 日志消息实体
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
public class LoggerMessage {
    private String body;
    private String timestamp;
    private String threadName;
    private String className;
    private String level;
    private String exception;
    private String cause;
//省略 get , set
}

5. 接下来配置WebSocket

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Autowired
    SimpMessagingTemplate messagingTemplate;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws/websocket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue","/topic");
    }

    @PostConstruct
    public void pushLogger(){
        ExecutorService executorService= Executors.newFixedThreadPool(2);
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        LoggerMessage log = LoggerQueue.getInstance().poll();
                        if(log!=null){
                            if(messagingTemplate!=null)
                            {
                                messagingTemplate.convertAndSend("/topic/pullLogger",log);
//                                System.out.println(new ObjectMapper().writeValueAsString(log));
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        executorService.submit(runnable);
    }
}

6.在vue中去接收消息。

           //建立日志连接
            initlog(context) {
                if (context.state.stompClient == null) {
                    context.res = "<div style='color: #18d035;font-size: 14px'>通道连接成功,静默等待....</div>"
                    // this.$refs['logContainerDiv'].append();
                    // 建立连接对象
                    let socket = new SockJS('http://localhost:8081/ws/websocket');
                    // 获取STOMP子协议的客户端对象
                    context.state.stompClient = Stomp.over(socket);
                    context.state.stompClient.connect({}, () => {
                        context.state.stompClient.subscribe('/topic/pullLogger', (event) => {
                                let content = JSON.parse(event.body);
                                // console.log(content);
                                let leverhtml = '';
                                let className = "<span style='color: #229379'>" + content.className + "</span>";
                                switch (content.level) {
                                    case 'INFO':
                                        leverhtml = "<span style='color: #90ad2b'>" + content.level + "</span>";
                                        break;
                                    case 'DEBUG':
                                        leverhtml = "<span style='color: #A8C023'>" + content.level + "</span>";
                                        break;
                                    case 'WARN':
                                        leverhtml = "<span style='color: #fffa1c'>" + content.level + "</span>";
                                        break;
                                    case 'ERROR':
                                        leverhtml = "<span style='color: #e3270e'>" + content.level + "</span>";
                                        break;
                                }
                                context.state.res += "<div style='color: #18d035;font-size: 14px'>" + content.timestamp + " " + leverhtml + " --- [" + content.threadName + "] " + className + " :" + content.body + "</div>"
                                // this.$refs['logContainerDiv'].append(content.timestamp + " " + leverhtml + " --- [" + content.threadName + "] " + className + " :" + content.body + "<br/>");
                                if (content.exception != "") {
                                    context.state.res += "<div>" + content.exception + "</div>"
                                    // this.$refs['logContainerDiv'].append();
                                }
                                if (content.cause != "") {
                                    context.state.res += "<div>" + content.cause + "</div>"
                                    // this.$refs['logContainerDiv'].append(content.cause);
                                }
                                // this.$refs['logContainer'].scrollTo(this.$refs['logContainerDiv'].height() - this.$refs['logContainer'].height());
                            },
                            // {
                            //     token: "kltoen"
                            // }
                        );
                    });
                }
            }

这只是一个连接websocket的代码,我们可以将获取到的信息保存在vue中的vuex中或者localStorage中进行持久化。

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
一个人若有一百只羊,一只走迷了路,你们的意思如何?他岂不撇下这九十九只,往山里去找那只迷路的羊吗?
519文章 67评论 191点赞 323857浏览

默认版本~SpringBoot2.0~2.3
  • Java—定时任务—HashedWheelTimer时间轮
  • Java—有向无环图(DAG)
  • JXLS—Excel模板框架
  • Disruptor—无锁队列
  • Redis—注解接口限流
  • SpringBoot—数据库读写分离
  • Netty—初探与核心(未完)
随便看看
ActiveMQ (4) Ajax (13) Docker (7) ElasticSearch (13) Enamiĝu al vi (1) Eureka (2) Feign (6) Freemarker (5) Gateway (6) Git (5) Hystrix (7) Java (78) Java Notes (117) JavaScript (1) jQuery (2) Kotlin Notes (47) Maven (2) More (2) MyBatis (42) MySQL (5) Netty (2) NOSQL (1) OAuth2 (11) PostgreSQL (4) RabbitMQ (6) Redis (18) Ribbon (6) Servlet (3) Spring (70) SpringBoot (85) SpringCloud (14) SpringJPA (4) SpringMVC (46) Spring Notes (43) SpringSecurity (49) SQL (15) SQL Notes (9) SQL Server (2) Thymeleaf (4) Vue (9) Web (12) Web Notes (18) WebSocket (9) XML (1) Zuul (3)
随便看看
  • 2023年5月 (2)
  • 2023年4月 (1)
  • 2023年3月 (1)
  • 2023年2月 (5)
  • 2023年1月 (4)
  • 2022年12月 (1)
  • 2022年11月 (3)
  • 2022年10月 (5)
  • 2022年9月 (8)
  • 2022年8月 (1)
  • 2022年7月 (2)
  • 2022年6月 (4)
  • 2022年5月 (5)
  • 2022年4月 (3)
  • 2022年3月 (7)
  • 2022年2月 (4)
  • 2022年1月 (15)
  • 2021年12月 (16)
  • 2021年11月 (3)
  • 2021年10月 (3)
  • 2021年9月 (3)
  • 2021年8月 (2)
  • 2021年7月 (4)
  • 2021年6月 (16)
  • 2021年5月 (3)
  • 2021年4月 (2)
  • 2021年3月 (13)
  • 2021年2月 (2)
  • 2021年1月 (33)
  • 2020年12月 (13)
  • 2020年11月 (6)
  • 2020年10月 (17)
  • 2020年9月 (26)
  • 2020年8月 (46)
  • 2020年7月 (28)
  • 2020年6月 (4)
  • 2020年5月 (16)
  • 2020年4月 (88)
  • 2020年3月 (104)
随机文章
Java—ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量
3年前
Kotlin-协程(专)—Flow 篇(四十一)
2年前
SpringBoot—文件上传(StandardServletMultipartResolver )
3年前
EasyExcel使用详解
3年前
SpringMVC笔记16—静态资源访问
3年前
Mybatis-Plus—多数据源
3年前
ENMAL摘要

1、Kotlin:

https://www.liuwj.me/

 

2、webflux:

https://www.cnblogs.com/lixinjie/p/a-brother-of-spring-mvc-is-spring-webflux.html

 

3、Java中的Unsafe

 

4、https://my.oschina.net/quanke/blog/1631990

 

5、https://blog.csdn.net/u013064109/article/details/78786646?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161214257916780264022540%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161214257916780264022540&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-11-78786646.first_rank_v2_pc_rank_v29&utm_term=kotlin

 

6、待学习除Spring之外的Web框架 — Cloudopt Next、Javalin、jfinal

https://jfinal.com/doc

 

7、kotlin设计模式——https://github.com/AboutKotlin/Design-Patterns-In-Kotlin

 

8、kotlin–ktorm+SpringBoot——https://gitee.com/tianchaohongyu/Spring-Boot-Ktor-Starter

 

9、新技术 — CQRS、jasync-sql、play!framework、akka、asyncdb

 

10、Kotlin Tips

https://gitee.com/lesliekoma/kotlin_tips?_from=gitee_search#tip5–%E6%87%92%E5%88%9D%E5%A7%8B%E5%8C%96by-lazy-%E5%92%8C-%E5%BB%B6%E8%BF%9F%E5%88%9D%E5%A7%8B%E5%8C%96lateinit

 

11、mall项目电商系统

https://github.com/macrozheng/mall

 

12、POI大量读写

https://www.cnblogs.com/swordfall/p/8298386.html

 

13、Gitee

权限RBAC:

https://gitee.com/log4j/pig

 

14、freecodecamp、pf4j

 

15、https://javadoop.com/

 

16、https://www.cnblogs.com/skywang12345/

 

17、Flyway

 

18、https://github.com/kotlin-orm/ktorm/pull/296

 

kt实体类自动生成表

 

https://github.com/tursom/TursomServer/tree/master/ts-database/src/main/kotlin/cn/tursom/database

 

19、蓝狐、支付沙盒、虚拟币

 

20、r2dbc spring强推,vertx这边是quarkus强推 redhat认证

 

21、Keycloak为Web应用和Restful服务提供了一站式的单点登录解决方案。

 

22、RSQL 的形式为 Restful API 带来了 SQL 声明性的便利

https://github.com/vineey/archelix-rsql

https://github.com/ymind/rsql-ktorm

 

23、Kotlin依赖注入

https://github.com/InsertKoinIO/koin

 

24、Kotlin– Alpas

https://github.com/alpas/alpas

一个基于 Kotlin 的 Web 框架,可让您简单快速地创建 Web 应用程序和 API。

 

25、外网学习网站,文章

https://medium.com/nerd-for-tech

 

26、Compose Multiplatform 进入 Alpha 版,统一桌面、Web 和 Android UI

https://blog.jetbrains.com/kotlin/2021/08/compose-multiplatform-goes- alpha/

 

27、Sureness

面向REST API的高性能认证鉴权框架,致力于管理保护API安全

https://gitee.com/dromara/sureness

与Javalin结合

https://javalin.io/2021/04/16/javalin-sureness-example.html

 

28、Kotlin官网合集库

https://kotlinlang.org/lp/server-side/

https://kotlinlang.org/lp/server-side/

https://kotlinlang.org/lp/server-side/

 

29、CLI知识体系

https://juejin.cn/post/6966119324478079007

 

30、面向 Web、移动和 Flutter 开发人员的安全开源后端服务器

https://appwrite.io/

 

31、Java锁

https://blog.csdn.net/hancoder/article/details/120421993

 

32、java—简单的鉴权认证

介绍 – Sa-Token (dev33.cn)

 

33、Effective Kotlin 中文翻译

GitHub – MaxzMeng/Effective-Kotlin-zh-CN: Effective Kotlin 中文翻译

 

34、Nutz—国产Web开源框架

http://www.nutzam.com/core/nutz_preface.html

 

35、Quarkus 夸克—国外开源框架

https://quarkus.io/

 

36、目前6个框架

  1. Spring Reactive → 背靠 Pivotal → 归属 VMware → 归属戴尔
  2. Quarkus 和 Vert.x → 背靠 Eclipse 基金会 → 主要由 Red Hat 支持
  3. Helidon → 背靠 Oracle
  4. Micronaut → 背靠 Object Computing(Grails、OpenDDS)
  5. Lagom → 背靠 Lightbend(Akka)
  6. Ktor → 背靠 JetBrains

 

37、XXL-JOB—–分布式任务调度平台

https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8B

 

38、领域设计驱动模版

https://myddd.org

 

39、BFF— Backend For Frontend

 

40、面试突击小册

https://snailclimb.gitee.io/javaguide-interview/#/

https://javaguide.cn/

 

41、JeecgBoot 是一款基于代码生成器的低代码开发平台

http://doc.jeecg.com/2043868

 

42、

IdentityServer4 是用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架。

https://identityserver4docs.readthedocs.io/zh_CN/latest/index.html

 

43、cn.novelweb 工具类的个人博客

https://blog.novelweb.cn

 

44、分布式链路追踪SkyWalking

 

45、刷题模版

https://blog.csdn.net/fuxuemingzhu/article/details/101900729

 

46、TS中文文档

https://ts.xcatliu.com/

 

47、Rust 中文文档

https://kaisery.github.io/trpl-zh-cn/ch00-00-introduction.html

 

48、Bean Searcher 只读 ORM

https://searcher.ejlchina.com/guide/latest/start.html

 

49、K8S的学习手册

https://kuboard.cn/learning/k8s-basics/kubernetes-basics.html#%E5%AD%A6%E4%B9%A0%E7%9B%AE%E6%A0%87

 

50、fluent-mybatis, mybatis语法增强框架(关键自动生成代码JavaPoet)

https://gitee.com/fluent-mybatis/fluent-mybatis?_from=gitee_search

 

51、程序猿博客

https://qicoder.com/categories/

https://blog.hhui.top/hexblog/

https://fangshixiang.blog.csdn.net/category_7941357_2.html

https://www.zhihu.com/people/zhuo-zi-yang-93

 

52、itxiaoshen大佬的分享

https://www.cnblogs.com/itxiaoshen/

 

53、MySQL实战学习

https://funnylog.gitee.io/mysql45/

 

54、八股文

https://www.javalearn.cn/#/

 

55、两个宣传很牛的IO框架

https://gitee.com/smartboot/smart-socket

https://www.tiocloud.com/doc/taixin/?pageNumber=1

 

56、GIS动态扩散模型

https://43.140.250.235/vue/#/

 

57、PGGIS大佬

https://blog.csdn.net/m0_60387551/article/details/123184049

 

58、有时间看一下的东西

Trino、presto、shenyu、Pigx

 

59、外网IT博客

https://kt.academy/article/dispatcher-loom

https://medium.com/

https://vived.io/blog/page/2/

https://vived.io/blog/page/2/

https://vived.io/blog/page/2/

https://www.bmpi.dev/dev/

 

60、源码阅读笔记

https://github.com/seaswalker/jdk-sourcecode-analysis

https://github.com/doocs/source-code-hunter

 

61、图书下载

http://www.ucdrs.superlib.net/

http://www.chendianrong.com/pdf#g

 

62、组件式规则引擎—liteflow

https://liteflow.yomahub.com/

 

Copyright © 2023 网站备案号: 浙ICP备20017730号
主页
页面
  • 归档
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
519 文章 67 评论 323857 浏览
测试
测试
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付