关于Freemarker模板引擎,需要知道这些
写在前面尽管在目前企业级的应用开发中,前后端分离是趋势,但是视图层技术还是占用一席之地。SpringBoot对视图层技术也提供了很好的支持,官方推荐使用的模板引擎是Thymeleaf,但是FreeMaker也支持,当然你可以像SSM中使用JSP等,但是非常不推荐使用。
FreeMarkerFreeMarker简介FreeMarker是一个非常古老的Java模板引擎,可以用在Web或者非Web环境中。与Thymeleaf不同的是FreeMarker需要经过解析才能够在浏览器中展示出来。FreeMarker不仅可以用来配置HTML页面模板,也可以作为电子邮箱模板、配置文件模板以及源码模板等。正是由于它可以适应不同的应用场景,因此它虽然古老但是依旧还是有人愿意使用它。
下面是一张摘自FreeMarker官网的图片:
可以看到FreeMarker可以将模板(Template)和数据(Java Objects)进行渲染为HTML页面。
FreeMarker模板文件及存放位置查看一下这个spring-boot-autoconfigure依赖的META-INF文件夹下面的spring.factor ...
自定义SpringBoot中的Starter场景启动器
写在前面在前面我们对SpringBoot的自动装配原理有了一个较为深刻的研究,那么接下来我们就分析一下其中的场景启动器(starter),并尝试自定义一个属于自己的场景启动器(starter)。
场景启动器简介场景启动器(starter),其实就是一个个的功能。SpringBoot会将用户常用的一些功能抽离出来,做成一个个的场景启动器,这些场景启动器会导入实现这些功能所需的全部依赖组件,这样开发者只需在项目中引入这些场景启动器,那么相应的依赖就会加载进来。开发者只需通过修改配置文件,就能实现使用相应功能这一目的。
父场景启动器介绍当我们新建一个SpringBoot项目时,POM文件中会自动添加一个父依赖,该依赖名称为spring-boot-starter-parent:
123456<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <versio ...
聊一聊SpringBoot的自动装配原理
写在前面最近在重构一个日志模块,需要将其从项目中抽离出来,于是考虑将其做成一个starter便于后续使用。本篇就来聊聊SpringBoot的自动装配原理,只有了解原理才知道如何将自己的项目制作为starter。
管中窥豹当你新建一个SpringBoot项目的时候,项目入口类中自动会添加@SpringBootApplication,那么问题来了,这个@SpringBootApplication注解的作用是什么呢,查看一下该注解的源码:
1234567891011121314151617@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilte ...
SpringBoot自定义参数解析器
写在前面今天我们来聊一聊SpringBoot中的参数解析器,这在某些场景下非常有用。一般来说,在一个Web请求里面参数要么是放在请求地址,要么就是放在请求体里面,极个别的会放在请求头中。
如果请求参数放在请求地址中,那么通常会采用@RequestParam/@PathVariable或者如下方式来获取参数:
1String username = request.getParameter("username");
如果请求参数放在请求体里面,那么通常会采用@RequestBody或者如下方式来获取参数:
1String username = request.getParameter("username");
如果请求参数放在请求头里面,那么通常会采用@RequestHeader或者如下方式来获取参数:
1String username = request.getHeader("username");
如果参数是JSON形式的,那么会从输入流中获取并解析成JSON字符串,再通过JSON工具转化为POJO对象:
1234Buffer ...
一个注解配合Redis实现接口限流
写在前面最近发现线上发送验证码的接口被莫名刷了,1天就把上周刚充值的1万条用完了,我内心其实是崩溃的,于是决定对该接口实现限流,这里选择使用拦截器配合Redis来实现。
实战项目初始化第一步,新建一个名为limit-redis的SpringBoot项目,然后在POM文件中添加如下依赖:
123456789101112131415161718<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>&l ...
可视化多数据源动态切换
写在前面在实际工作中我们希望实现多数据源的动态切换,而这一点我们在前面一篇文章中就已经进行了实现,但是对于业务人员来说,更多的则是希望可以通过可视化界面的方式来自己决定使用哪个数据源,进而获取对应的数据。
几个思考前面我们多次提到AbstractRoutingDataSource抽象类定义了抽象的determineCurrentLookupKey方法,子类只需实现此方法,就可以通过一个Key从Map中获取对应的数据源实例,并执行对应的数据库操作。查看一下之前我们的dynamic-multiple-ds项目,本篇将在此基础上进行实现。由于我们将数据源名称存在DynamicMultipleDataSourceContextHolder这一ThreadLocal中,因此只需修改该变量的值就能实现这个目的。
也就是说首先我们要定义一个方法用于传入新的数据源名称,然后我们可以将这个数据源名称放在Session、Redis或者数据库中,最后在修改DynamicMultipleDataSourceContextHolder的时候从里面取出数据并更新ThreadLocal的值即可。
其次,用户通过页面 ...
多数据源动态切换
写在前面在前一篇文章中我们介绍了如何在SpringBoot中整合Jdbc Template、Mybatis和Spring Data JPA的多数据源配置,但是很明显这些思路都是设置多个Dao层,然后手动选择使用的实例,在实际工作中可能会有需要动态切换数据源的情况,因此本篇来学习如何利用AOP来实现多数据源的动态切换功能。
知识回顾AbstractRoutingDataSource是Spring2.0.1版本引入的一个抽象类,它提供了多数据源的支持能力。AbstractRoutingDataSource抽象类定义了抽象的determineCurrentLookupKey方法,子类只需实现此方法,进而动态确定要使用的数据源。
查看一下这个AbstractRoutingDataSource抽象类的源码,如下所示:
1234567891011121314151617181920212223242526272829303132public abstract class AbstractRoutingDataSource extends AbstractDataSource implements ...
SpringBoot配置多数据源
写在前面本篇来学习SpringBoot如何配置多数据源,所谓多数据源就是一个Java EE项目中采用了不同数据库实例中的多个库,或者是同一个数据库实例中的多个不同库。一般来说,采用MyCat等分布式数据库中间件是比较好的解决方案,这样可以把数据库读写分离、分库分表、备份等操作交给中间件去做,这样Java代码只需要专注于业务即可。不过这并不意味着无法使用Java代码解决类似的问题,在Spring Famework中就可以配置多个数据源,SpringBoot作为其中的佼佼者,自然也同样支持多数据源的配置,只是配置方式有些变化而已。
下面就分别介绍使用Jdbc Template、Mybatis和SpringData JPA等不同持久层框架时的多数据源配置。
Jdbc Template多数据源Jdbc Template多数据源配置是最简单的一个,因为一个Jdbc Template就对应一个DataSource,开发者只需要提供多个DataSource,再手动配置Jdbc Template即可。具体配置如下:第一步,创建数据库。使用下面的SQL语句来手动创建两个数据库和表:
1234567891 ...
Druid数据库连接池使用体验
写在前面在实际工作中我们我们使用较多的则是Spring默认的HikariDataSource数据库连接池,但是它无法提供可视化监控SQL这一能力,而这在很多场景下往往又是我们需要的功能,因此今天来学习阿里开源的一款优秀的数据库连接池—Druid。Druid能够提供强大的SQL监控和功能扩展能力,允许开发者根据需要进行二次开发。
实战首先我们使用传统的方式,快速搭建一个具备查询用户信息的简单项目。
项目初始化第一步,新建一个名为druid-sql的SpringBoot项目,选择spring web、mybatis framework和mysql driver依赖:
第二步,修改application.properties配置文件信息:
1234spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql:///druid_sql?serverTimezone=Asia/Shanghaispring.datasource.username=rootspring.datas ...
Dart面向对象基础
方法(函数)方法定义Dart是一个面向对象的语言,因此函数也是对象,属于Function对象。方法定义格式如下:
1234返回类型 方法名(参数1,参数2,...) { 方法体... return 返回值;}
可以看到它其实和Java中方法的定义很像,所不同的是最前面没有方法的访问修饰符。
Dart中的方法的返回值类型和参数类型都可以省略。这里面还有一个箭头语法=> expr,它其实是{ return expr };的缩写,只适用于一个表达式。方法都有返回值,如果没有指定,那么默认return null最后一句执行。
举个例子,下面的代码表示输出用户输入的参数信息:
123void main(List args){ print(args);}
如何让用户输入信息呢?在Dart中只需进入到该文件,然后使用dart 文件名.dart命令,后面再跟上需要输入的参数即可:
12E:\DartProjects\hellodart\dart_basic\function> dart myfunction.dart ...