Spring Boot
文章平均质量分 78
各种入门
weixin_42073629
这个作者很懒,什么都没留下…
展开
-
SpringBoot+Kafka+ELK 完成海量日志收集
整体流程大概如下:服务器准备在这先列出各服务器节点,方便同学们在下文中对照节点查看相应内容图片推荐下自己做的 Spring Boot 的实战项目:https://github.com/YunaiV/ruoyi-vue-proSpringBoot项目准备引入log4j2替换SpringBoot默认log,demo项目结构如下:图片pom<dependencies><dependency><gro...原创 2021-09-04 17:41:46 · 131 阅读 · 0 评论 -
Spring Boot 容器选择
Spring Boot 内嵌容器Undertow参数设置配置项:# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程# 不要设置过大,如果过大,启动项目会报错:打开文件数过多server.undertow.io-threads=16# 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程# 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8server.undertow.w.原创 2021-06-07 00:29:04 · 365 阅读 · 0 评论 -
SpringBoot中必须掌握的45个注解
1.SpringBoot/spring@SpringBootApplication:包含@Configuration、@EnableAutoConfiguration、@ComponentScan通常用在主类上;@Repository:用于标注数据访问组件,即DAO组件;@Service:用于标注业务层组件;@RestController:用于标注控制层组件(如struts中的action),包含@Controller和@ResponseBody;@Controller:原创 2021-05-26 21:44:55 · 122 阅读 · 0 评论 -
Spring Boot 接入支付宝
支付宝推出了新的转账接口alipay.fund.trans.uni.transfer(升级后安全性更高,功能更加强大) ,老转账接口alipay.fund.trans.toaccount.transfer将不再维护,新老接口的一个区别就是新接口采用的证书验签方式。使用新接口要将sdk版本升级到最新版本,博主升级时最新版本是4.10.97。接下来看集成步骤。1.将支付宝开放平台里下载的3个证书放在resources下面2.写支付宝支付的配置文件alipay.propertiesa原创 2021-05-16 18:17:40 · 317 阅读 · 0 评论 -
Spring Security OAuth2 入门新
1. 概述在《Spring Boot 安全框架 Spring Security 入门》文章中,分享了如何使用 Spring Security 实现认证与授权的功能,获得广大女粉丝的好评。于是乎,艿艿准备再来分享一波Spring Security OAuth框架,看看在 Spring Security 如何实现 OAuth2.0 实现授权的功能。旁白君:实际上艿艿很早写了一篇关于 Spring Security OAuth 的文章,考虑到版本太老,提供的示例又过于简单,所以本文也是该文章的升..原创 2021-04-05 01:32:45 · 810 阅读 · 0 评论 -
Springboot集成FastDFS
加入依赖<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.26.2</version></dependency>在springboot启动类上加@Import(FdfsClientConfig.class)@EnableMB...原创 2021-03-21 03:55:16 · 222 阅读 · 0 评论 -
SpringBoot 注解原理
首先,先看SpringBoot的主配置类:@SpringBootApplicationpublicclassStartEurekaApplication{publicstaticvoidmain(String[]args){SpringApplication.run(StartEurekaApplication.class,args);}}点进@SpringBootApplication来看,发现@SpringBootAppli...原创 2021-03-21 03:28:18 · 189 阅读 · 0 评论 -
springboot集成调用Azkaban
一、 说明 1.Azkaban是由Linkedin公司推出的一个批量工作流任务调度器,主要用于在一个工作流内以一个特定的顺序运行一组工作和流程,它的配置是通过简单的key:value对的方式,通过配置中的dependencies 来设置依赖关系,这个依赖关系必须是无环的,否则会被视为无效的工作流。Azkaban使用job配置文件建立任务之间的依赖关系,并提供一个易于使用的web用户界面维护和跟踪你的工作流。 2.springboot版本:2.0.5 azkaban版本:3.59.0...原创 2020-09-29 21:23:00 · 1105 阅读 · 0 评论 -
Spring Boot Dubbo 入门
1. 概述在 2019.05.21 号,在经历了 1 年多的孵化,Dubbo 终于迎来了 Apache 毕业。在这期间,Dubbo 做了比较多的功能迭代,提供了 NodeJS、Python、Go 等语言的支持,也举办了多次社区活动,在网上的“骂声”也少了。艿艿:事实上,大多数成熟的开源项目,都是 KPI 驱动,又或者背后有商业化支撑。作为一个长期使用,并且坚持使用 Dubbo 的开发者,还是比较愉快的。可能,又经历了一次技术正确的选择。当然,更愉快的是,Spring Cloud Alibab原创 2020-08-05 23:47:10 · 856 阅读 · 0 评论 -
Spring Boot 监控平台 CAT 入门
1. 概述在《CAT 极简入门》文章中,我们一起完成了 CAT 的学习,并完成了 CAT 服务器的搭建。本文,我们将使用 CAT 提供的Java 客户端客户端,接入 Spring Boot 应用中,实现应用监控的功能。2. 快速入门示例代码对应仓库:lab-61-demo。在 CAT 中,一共有四种监控模型:Transaction:适合记录跨越系统边界的程序访问行为,比如远程调用,数据库调用,也适合执行时间较长的业务逻辑监控。Transaction 用来记录一段代码的执行时...原创 2020-06-20 12:21:06 · 2857 阅读 · 2 评论 -
Spring Boot 链路追踪 SkyWalking 入门
1. 概述如果胖友还没了解过分布式链路追踪SkyWalking,建议先阅读下艿艿写的《SkyWalking 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 SkyWalking》,哈哈哈。可能会有胖友会有疑惑,Spring Boot 不是一个单体应用么,为什么可以使用 SkyWalking 进行分布式链路追踪呢?其实这里有一个误区!即使是一个 Spring Boot 单体应用,我们一般可能会和以下服务打交道:关系数据库,例如说 MySQL、Oracle、SQL...原创 2020-06-16 21:44:46 · 67243 阅读 · 2 评论 -
Spring Boot 链路追踪 Zipkin 入门
1. 概述如果胖友还没了解过分布式链路追踪Zipkin,建议先阅读下艿艿写的《Zipkin 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 Zipkin》,哈哈哈。可能会有胖友会有疑惑,Spring Boot 不是一个单体应用么,为什么可以使用 Zipkin 进行分布式链路追踪呢?其实这里有一个误区!即使是一个 Spring Boot 单体应用,我们一般可能会和以下服务打交道:关系数据库,例如说 MySQL、Oracle、SQLServer、PostgreSQ...原创 2020-06-16 22:35:10 · 2699 阅读 · 0 评论 -
Spring Boot 日志平台 ELK + Filebeat 入门
1. 概述在《芋道 Spring Boot 日志集成 Logging 入门》文章中,我们学习了 Spring Boot 如何集成并使用日志框架,进行日志的打印。友情提示:对于本文来说,即使胖友未阅读过《芋道 Spring Boot 日志集成 Logging 入门》文章,也毫无影响,不要慌~不过正如我们在文末所说,在生产环境下,我们会集群部署我们的应用。那么我们可能需要登陆多台服务器,查看不用应用节点下的日志,这样会非常不方便。所以,本文我们就一起来,使用 ELK + Filebeat 组原创 2020-06-16 02:06:23 · 2009 阅读 · 0 评论 -
Spring Boot 日志集成 Logging 入门
1. 概述在开始讲解在 Spring Boot 如何使用日志框架之前,我们想来了解下 Java 日志框架的生态,以便我们更深入的入门。当然,胖友也可以选择跳过,直接从「2. 快速入门」小节开始。1.1 日志框架在 Java 日志框架的生态中,存在多种的日志实现框架。例如说: JUL Java 自带java.util.logging组件的简称。 Apache Log4j1 Apache Log4j2 Logback那么,对于 Spring、Hibernat..原创 2020-06-16 01:56:46 · 1442 阅读 · 0 评论 -
Spring Boot 监控平台 Prometheus + Grafana 入门
1. 概述在《芋道 Spring Boot 监控工具 Admin 入门》文章中,我们学习了如何使用 Spring Boot Admin 作为 Spring Boot 应用的监控和管理工具。友情提示:对于本文来说,即使胖友未阅读过《芋道 Spring Boot 监控工具 Admin 入门》文章,也毫无影响,不要慌~不过正如我们在文末所说,Spring Boot Admin 是个轻量级的监控工具,默认无法提供历史监控数据的查询,这对我们在排查问题时,可能不是特别不便利。所以,本文我们就一起来原创 2020-06-15 21:55:58 · 957 阅读 · 0 评论 -
Spring Boot 监控工具 Admin 入门
1. 概述在《Spring Boot 监控端点 Actuator 入门》中,我们学习了通过 Actuator 端点,通过 HTTP 请求,获得应用的审计(auditing)、健康状况(health)和指标(metrics)等数据。不过正如我们在文末所说,直接请求 Actuator 端口,查看监控数据,是非常低效且使用体验较差的。所以我们的一个解决方案是Spring Boot Admin监控工具,也是本文我们要学习的。其官方文档介绍如下:FROM《Spring Boot Admin Ref...原创 2020-06-15 21:47:07 · 1682 阅读 · 0 评论 -
Spring Boot 监控端点 Actuator 入门
1. 概述现在在阅读本文的胖友,估计绝大多数都是 Java 开发者。很多时候,我们只关心开发部分,但是应用在部署在生产环境下,我们还需要考虑应用的管理与监控。例如说,应用是否健康存活、应用的 JVM 监控信息、服务器的监控信息(CPU、内存、磁盘等等)。如果我们为应用的管理与监控做相应的开发,是需要一定的成本的。幸运的是,在 Spring Boot 框架提供了一个非常重要的新组件spring-boot-actuator。其文档介绍如下:FROM《Spring Boot Actuator:...原创 2020-06-15 21:27:52 · 1419 阅读 · 0 评论 -
Spring Boot 服务容错 Sentinel 入门
1. 概述在《Sentinel 极简入门》中,我们简单了解了 Sentinel,并搭建了 Sentinel 控制台。如果还没看的胖友,可以先看看该文的「1. 概述」和「2. 控制台」小节。Sentinel 功能比较强大,同时胖友可能对服务容错可能比较陌生,所以我们跟着示例,一个一个来学习噢。2. 流量控制示例代码对应仓库:lab-46-sentinel-demo。在本小节,我们来学习下 Sentinel 的流量控制功能,对应《Sentinel 官方文档 —— 流量控制》文章。F原创 2020-05-30 19:02:27 · 2107 阅读 · 0 评论 -
Spring Boot 服务容错 Hystrix 入门
1. 概述在开始 Hystrix 的学习之前,我们先来一起瞅瞅“服务雪崩”、“服务容错”等的概念,方便我们理解为什么要使用 Hystrix 框架。友情提示:本文是《芋道 Spring Cloud Netflix 服务容错 Hystrix 入门》的弟弟篇。所以内容上,会有蛮多重叠的地方。写本文的主要目的是,分享在纯 Spring Boot环境下,如何使用 Hystrix 框架。基本所有的网上文章,都是通过Spring Cloud Netflix Hystrix进行 Hystrix 的使用,...原创 2020-05-28 23:59:32 · 850 阅读 · 0 评论 -
SpringBoot 数据库管理与迁移(Liquibase)
目前Spring Boot支持较好的两款工具分别是flyway、liquibase,支持sql script,在初始化数据源之后执行指定的脚本代码或者脚本文件,本章基于Liquibase…LiquibaseLiquiBase是一个用于数据库重构和迁移的开源工具,通过changelog文件的形式记录数据库的变更,然后执行changelog文件中的修改,将数据库更新或回滚到一致的状态。主要特点支持几乎所有主流的数据库,如MySQL、PostgreSQL、Oracle、Sq...原创 2020-05-26 01:18:58 · 577 阅读 · 0 评论 -
SpringBoot 轻松搞定重复提交(分布式锁)
单机版的重复提交解决方案,在如今这个分布式与集群横行的世道中,那怎么够用呢,所以本章重点来了....重复提交(分布式)单机版中我们用的是Guava Cache,但是这玩意存在集群的时候就凉了,所以我们还是要借助类似Redis、ZooKeeper 之类的中间件实现分布式锁。本章目标利用自定义注解、Spring Aop、Redis Cache实现分布式锁,你想锁表单锁表单,想锁接口锁接口….具体代码也很简单…导入依赖在pom.xml中添加上starter-web、sta...原创 2020-05-26 00:33:39 · 575 阅读 · 0 评论 -
SpringBoot 轻松搞定重复提交(本地锁)
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交….重复提交字面意思就是提交了很多次,这种情况一般都是前端给你挖的坑….前段时间在开发中遇到一个这样的问题;前端小哥哥调用接口的时候存在循环调用的问题,正常情况下发送一个请求添加一条数据,结果变成了同一时刻并发的发送了 N 个请求,服务端瞬间懵逼的插入了 N 条一模一样的数据,前端小哥哥也不知道问题在哪里(恩....原创 2020-05-26 00:26:25 · 386 阅读 · 0 评论 -
SpringBoot 轻松搞定全局异常
实际项目开发中,程序往往会发生各式各样的异常情况,特别是身为服务端开发人员的我们,总是不停的编写接口提供给前端调用,分工协作的情况下,避免不了异常的发生,如果直接将错误的信息直接暴露给用户,这样的体验可想而知,且对黑客而言,详细异常信息往往会提供非常大的帮助…初窥异常一个简单的异常请求的接口@GetMapping("/test1")public String test1() { // TODO 这里只是模拟异常,假设业务处理的时候出现错误了,或者空指针了等等... int .原创 2020-05-25 00:26:58 · 124 阅读 · 0 评论 -
SpringBoot 轻松搞定文件上传
文件上传文件上传和下载是JAVA WEB中常见的一种操作,文件上传主要是将文件通过IO流传输到服务器的某一个特定的文件夹下;刚开始工作那会一个上传文件常常花费小半天的时间,繁琐的代码量以及XML配置让我是痛不欲生;值得庆幸的是有了Spring Boot短短的几句代码就能实现文件上传与本地写入操作….导入依赖在pom.xml中添加上spring-boot-starter-web和spring-boot-starter-thymeleaf的依赖<dependencies>...原创 2020-05-25 00:06:57 · 167 阅读 · 0 评论 -
Spring Boot 注册中心 Nacos 入门
1. 概述在《Nacos 极简入门》中,我们已经学习了如何搭建一个 Nacos 服务。如果还没有的胖友,赶紧先去简单学习下,重点是跟着该文「2. 单机部署」小节,自己搭建一个 Nacos 服务。本文,我们来学习下如何在 Spring Boot 中,将 Nacos 作为一个注册中心,实现分布式环境下的服务注册与发现。友情提示:对 Nacos 作为配置中心感兴趣的胖友,可以看看《芋道 Spring Boot 配置中心 Nacos 入门》文章。2. 注册中心原理在使用注册中心时,一共有三种原创 2020-05-23 23:01:41 · 1291 阅读 · 1 评论 -
Spring Boot 配置中心 Apollo 入门
1. 概述在《Apollo 极简入门》中,我们已经学习了如何搭建一个 Apollo 服务。如果还没有的胖友,赶紧先去简单学习下,重点是跟着该文「2. 单机部署」小节,自己搭建一个 Apollo 服务。本文,我们来学习下如何在 Spring Boot 中,将 Apollo 作为一个配置中心,实现分布式环境下的配置管理。2. 快速入门示例代码对应仓库:lab-45-apollo-demo。本小节,我们会在 Apollo 服务中定义配置,并使用 并使用@ConfigurationProp.原创 2020-05-23 20:13:41 · 1393 阅读 · 0 评论 -
Spring Boot 配置中心 Nacos 入门
1. 概述在《Nacos 极简入门》中,我们已经学习了如何搭建一个 Nacos 服务。如果还没有的胖友,赶紧先去简单学习下,重点是跟着该文「2. 单机部署」小节,自己搭建一个 Nacos 服务。本文,我们来学习下如何在 Spring Boot 中,将 Nacos 作为一个配置中心,实现分布式环境下的配置管理。友情提示:对 Nacos 作为注册中心感兴趣的胖友,可以看看《芋道 Spring Boot 注册中心 Nacos 入门》文章。2. 快速入门示例代码对应仓库:lab-44-na原创 2020-05-23 19:51:23 · 6058 阅读 · 1 评论 -
Spring Boot 配置文件入门
1. 概述经历过早期Spring 年代的胖友,肯定会有和艿艿一样的感受,在享受 Spring 提供的强大的功能的同时,使用 XML 配置真的是好特喵的繁琐。而这个情况,Spring 提供了JavaConfig又稍好了一些。最终,Spring Boot 的诞生,基于 JavaConfig 提供自动化配置,把我们从配置的泥潭之中,进一步解放。在使用 Spring Boot 时,我们仅需在pom.xml文件中,引入需要组件的*-starter依赖,并在application.yaml等配...原创 2020-05-23 18:41:13 · 1431 阅读 · 0 评论 -
Spring Boot 事件机制 Event 入门
1. 概述在设计模式中,观察者模式是一个比较常用的设计模式。维基百科解释如下:FROMhttps://zh.wikipedia.org/wiki/观察者模式观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。在我们日常业务开发中,观察者模式对我们很大的一个作用,在于实现业务的解耦。以用户注册的场景来举例子,假设在用户注册完成时,需要.原创 2020-05-23 17:43:39 · 2491 阅读 · 0 评论 -
Spring Boot 消息队列 ActiveMQ 入门
1. 概述如果胖友还没了解过分布式消息队列ActiveMQ,建议先阅读下艿艿写的《芋道 ActiveMQ 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 ActiveMQ》,哈哈哈。考虑这是 ActiveMQ 如何在 Spring Boot 整合与使用的文章,所以还是简单介绍下 ActiveMQ 是什么?FROM《JMS 消息服务器 ActiveMQ》ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是...原创 2020-05-22 23:21:24 · 387 阅读 · 0 评论 -
Spring Boot 消息队列 RabbitMQ 入门
1. 概述如果胖友还没了解过分布式消息队列RabbitMQ,建议先阅读下艿艿写的《芋道 RabbitMQ 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 RabbitMQ》,哈哈哈。考虑这是 RabbitMQ 如何在 Spring Boot 整合与使用的文章,所以还是简单介绍下 RabbitMQ 是什么?FROM《AMQP 消息服务器 RabbitMQ》RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing...原创 2020-05-21 22:09:28 · 544 阅读 · 0 评论 -
Spring Boot 消息队列 Kafka 入门
1. 概述如果胖友还没了解过分布式消息队列Apache Kafka,建议先阅读下艿艿写的《芋道 Kafka 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 Kafka》,哈哈哈。考虑这是 Kafka 如何在 Spring Boot 整合与使用的文章,所以还是简单介绍下 Kafka 是什么?FROM《分布式发布订阅消息系统 Kafka》Kafka 是一种高吞吐量的分布式发布订阅消息系统,她有如下特性:通过 O(1) 的磁盘数据结构提供消息的持久化,...原创 2020-05-20 23:56:34 · 948 阅读 · 0 评论 -
Spring Boot 消息队列 RocketMQ 入门
1. 概述如果胖友还没了解过分布式消息队列Apache RocketMQ,建议先阅读下艿艿写的《芋道 RocketMQ 极简入门》文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 RocketMQ》,哈哈哈。考虑这是 RocketMQ 如何在 Spring Boot 整合与使用的文章,所以还是简单介绍下 RocketMQ 是什么?FROM《消息中间件 Apache RocketMQ》RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延...原创 2020-05-19 23:56:41 · 808 阅读 · 0 评论 -
Spring Boot 异步任务入门
1. 概述在日常开发中,我们的逻辑都是同步调用,顺序执行。在一些场景下,我们会希望异步调用,将和主线程关联度低的逻辑异步调用,以实现让主线程更快的执行完成,提升性能。例如说:记录用户访问日志到数据库,记录管理员操作日志到数据库中。异步调用,对应的是同步调用。同步调用:指程序按照 定义顺序 依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行; 异步调用:指程序在顺序执行时,...原创 2020-05-05 01:57:45 · 332 阅读 · 0 评论 -
Spring Boot 定时任务入门
1. 概述在产品的色彩斑斓的黑的需求中,有存在一类需求,是需要去定时执行的,此时就需要使用到定时任务。例如说,每分钟扫描超时支付的订单,每小时清理一次日志文件,每天统计前一天的数据并生成报表,每个月月初的工资单的推送,每年一次的生日提醒等等。其中,艿艿最喜欢“每个月月初的工资单的推送”,你呢?在 JDK 中,内置了两个类,可以实现定时任务的功能:java.util.Timer...原创 2020-05-05 01:24:23 · 977 阅读 · 0 评论 -
Spring Boot Shiro 入门
1. 概述艿艿:本文是《芋道 Spring Boot 安全框架 Spring Security 入门》的姊妹篇,所以开头就“重复”再来一遍,嘿嘿。基本上,在所有的开发的系统中,都必须做认证(authentication)和授权(authorization),以保证系统的安全性。???? 考虑到很多胖友对认证和授权有点分不清楚,艿艿这里引用一个网上有趣的例子:FROM《认证 (aut...原创 2020-05-04 16:44:29 · 493 阅读 · 0 评论 -
Spring Boot Security OAuth2 入门
1. 概述本文,我们来入门 Spring Security OAuth2.0 的使用。通过本文,希望你对 OAuth2.0 有一次身临其境的感受。另外,这是一篇入门的文章,所以实际场景下,需要做一些微调。当然,需要微调的地方,笔者会在示例中说明,以免误导。如果你是 OAuth2.0 的萌新,建议先通读阮一峰大神的《理解OAuth 2.0》。因为,本文不会去阐述 OAuth2.0 概念...原创 2020-05-02 17:58:35 · 2171 阅读 · 0 评论 -
Spring Boot 安全框架 Spring Security 入门
1. 概述基本上,在所有的开发的系统中,都必须做认证(authentication)和授权(authorization),以保证系统的安全性。???? 考虑到很多胖友对认证和授权有点分不清楚,艿艿这里引用一个网上有趣的例子:FROM《认证 (authentication) 和授权 (authorization) 的区别》authentication [ɔ,θɛntɪ'keʃən] 认证...原创 2020-04-30 02:19:15 · 4985 阅读 · 2 评论 -
Spring Boot 分布式事务 Seata 入门
1. 概述在《芋道 Seata 极简入门》文章中,我们对 Seata 进行了简单的了解,并完成了 Seata 的部署。而本文,我们将纯Spring Boot 应用接入 Seata 来实现分布式事务。Seata是阿里开源的一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。2. AT 模式 + 多数据源示例代码对应仓库:lab-52-multiple-...原创 2020-04-29 00:15:55 · 1478 阅读 · 1 评论 -
Spring Boot Elasticsearch 入门
1. 概述如果胖友之前有用过 Elasticsearch 的话,可能有过被使用的 Elasticsearch 客户端版本搞死搞活。如果有,那么一起握个抓。所以,我们在文章的开始,先一起理一理这块。Elasticsearch(ES)提供了两种连接方式: transport :通过 TCP 方式访问 ES 。 对应的库是org.elasticsearch.client.tran...原创 2020-04-28 23:11:26 · 474 阅读 · 0 评论