关于springboot:MybatisPlusMP

以对象的形式操作数据库需要剖析1.对象与数据库表如何映射? 利用注解实现对象与表绑定,属性与字段绑定2.如何解决泛滥接口雷同的CURD操作 定义一个公共的Mapper接口,定义公共的CURD操作,利用泛型辨别对象3.如何将对象转换为sql 思维:依照特定的语法,将对象转发为sql语句例子:将user对象插入数据库userMapper.insert(user对象); //程序员的最初代码,具体的sql语句由框架生成sql:insert into 表名(字段...)valuses(属性的值...);由MP动静拼接,最初交给mybatis执行SpringBoot整合MybatisPlus增加依赖<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency>增加注解@Data@Accessors(chain = true)@TableName("user") //实现表与对象的依赖 如果名称统一(疏忽大小写)能够省略表名 @TableNamepublic class User implements Serializable { @TableId(type = IdType.AUTO) private Integer id; //主键,并且主键自增 //@TableField(value = "name") //能够省略 private String name; private Integer age; private String sex;}继承BaseMapper<> 批改yml配置文件mybatis-plus: #定义别名包 type-aliases-package: com.jt.pojo #增加.xml文件依赖 mapper-locations: classpath:/mybatis/mappers/*.xml #开启驼峰映射 configuration: map-underscore-to-camel-case: true测试类调用@Test public void test02(){ List<User> userList=userMapper.selectList(null); System.out.println(userList); }

August 26, 2020 · 1 min · jiezi

关于springboot:SpringBoot入门

Spring boot 入门1.筹备工作工具下载(1)下载JDK1.8,并进行环境变量配置(如果已有则无需再次下载和配置)。(2)下载最新maven(例如apache-maven-3.6.3,网址http://maven.apache.org/(http://maven.apache.org/))并解压。 下载sts最新版(例如sts-4.4.5.RELEASE,网址https://spring.io/tools(https://spring.io/tools)文件。 2.Maven的配置(1)关上maven中的setting.xml文件,并对其如下选项进行配置。 配置maven本地库(从maven近程服务器下载的资源存储到的地位)<localRepository>d:/local/repository</localRepository>配置maven私服(配置到mirrors标签外部)。 <mirror><id>aliyun</id><name>aliyun for maven</name><mirrorOf>\*</mirrorOf><url>https://maven.aliyun.com/repository/public</url> </mirror>配置maven中的profile(配置到profiles标签外部),设置JDK编译和运行版本。 <profile> <id>jdk-1.8</id> <activation><activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion> 1.8 </maven.compiler.compilerVersion></properties> </profile>3.Maven整合到sts* * *

August 26, 2020 · 1 min · jiezi

关于springboot:SpringBoot加强01

之前的文章中进行过springboot的一些应用,再说一说一些增强的内容. SpringBoot启动原理阐明咱们都晓得springboot非常弱小,能够实现零配置/少配置运行,以及开箱即用的个性,那么他是怎么做到的呢? pom.xml当咱们创立一个springboot我的项目,并只在创立时导入spring web依赖时能够看到pom.xml中有什么配置: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jt</groupId> <artifactId>springboot_demo1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_demo1</name> <description>入门案例</description> <!--parent标签作用: 定义了SpringBoot中所有关联我的项目的版本号信息.--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <java.version>1.8</java.version> <!--我的项目打包时,跳过测试类打包--> <skipTests>true</skipTests> </properties> <!--开箱即用:SpringBoot我的项目只须要引入大量的jar包及配置,即可领有其性能. spring-boot-starter 领有开箱即用的能力. maven我的项目中依赖具备传递性. A 依赖 B 依赖 C我的项目 导入A bc会主动依赖 --> <dependencies> <!--间接依赖web springMVC配置--> <dependency> <groupId>org.springframework.boot</groupId> <!--springBoot-start SpringBoot启动项 --> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--SpringBoot重构了测试形式 能够在测试类中 间接引入依赖对象--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <!--在我的项目打包部署时失效,如果不增加build,则程序公布时不然会报 我的项目中没有main办法. --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>pom.xml文件内标签的含意在上述代码中有所正文. ...

August 25, 2020 · 1 min · jiezi

关于springboot:Spring-Boot-快速入门1

Spring BootSpring Boot 的作用使开发人员不再须要大量的xml配置不再须要大量的手动依赖治理简化spring框架的配置~~~~ Spring Boot 疾速入门1.创立Spring Starter我的项目基于STS内置start创立第一步:关上sts软件,快捷键ctrl+n关上新建窗口,如图所示第二步:输出我的项目相干信息,如图所示:第三步:抉择SpringBoot版本,如图所示:第四步:我的项目构造展现,我的项目创立完当前的构造如下: 2. 我的项目业务初步实现及测试基于SpringBoot脚手架(或者架子工),通过Spring框架进行Bean对象的治理实现。第一步:创立一个DefaultCache类,存储到src/main/java目录,而后交给spring治理。 `package com.cy.pj.common.cache; @Component public class DefaultCache {}`其中,@Component是Spring中用于形容Bean类的一个注解。用于通知Spring这个类的实例由Spring创立,当此对象由Spring创立和治理时,默认会将对象存储到池(Bean池)中。第二步:增加sringboot 测试类,进行bean的获取及测试,要放在src/test/java目录中:`package com.cy.pj.common.cache; @SpringBootTest public class DefaultCacheTests { @Autowired private DefaultCache defaultCache; @Test public void testCache() { System.out.println(defaultCache); } }`其中: @SpringBootTest 注解用于通知spring框架,此测试类交给spring治理。@Autowired注解形容属性时,用于通知spring框架要为此属性注入一个值?(至于注入规定,前面课程缓缓增强)

August 25, 2020 · 1 min · jiezi

关于springboot:SpringBoot入门

SpringBoot入门1.SpringBoot简介1.1 Spring Boot概述当初软件市场曾经造成肯定的规模,零碎架构的复杂度也越来越高(例如有单体架构,分布式架构,微服务架构)。软件的整个架构体系正在产生很大变动,在这种变动中,企业当初更重视技术的开箱即用,更重视技术在生态圈中的深度交融,更重视轻量级的运维。由此spring boot诞生。阐明:学技术肯定要理解技术发展史,并对技术的倒退有肯定的前瞻性。 1.2 Spring Boot外围个性起步依赖(Strart Dependency) -我的项目创立时底层帮你关联依赖主动拆卸(Auto Configuration)健康检查(Actator) -监控Spring Boot官网地址: http://spring.io/projects/spring-boot2.SpringBoot环境配置2.1 筹备工作工具下载:1.下载JDK1.8,并进行环境配置。2.下载最新maven3.下载sts最新版并解压(新版本下载下来时一个.jar文件)工作区筹备:定义新的工作区(要求没有中文目录)2.2 Maven 根本配置关上maven中的setting.xml 文件,并对其如下选项进行配置。 配置maven本地库 (从maven近程服务器下载的资源存储到的地位) `<localRepository>${user.home}/.m5/repository</localRepository>`配置maven私服(配置到mirrors标签外部)。 <mirror> <id>aliyun</id> <name>aliyun for maven</name> <mirrorOf>\*</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror>配置maven中的profile(配置到profiles标签外部),设置JDK编译和运行版本。<profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion> 1.8 </maven.compiler.compilerVersion> </properties> </profile>2.3 STS整合 maven 配置2.3.1 启动STS工具(非凡的eclipse,增加了spring开发插件)2.3.2 Maven Installations配置, 如图所示: 2.3.3 Maven User Settings配置,如图所示: 2.4 STS 工具应用根本优化(可选)2.4.1 禁用拼写查看, 勾销图中所示的拼写查看选项 2.4.2 勾销图中所示的连贯选项配置 2.4.3 关掉图中的校验性能 2.4.4 批改STS工具内存配置,关上SpringToolSuite4.ini文件,批改堆大小,如图所示: 3.Spring Boot 疾速入门3.1我的项目创立及构造剖析关上STS 集成开发工具,创立spring boot我的项目,其具体步骤如下: ...

August 25, 2020 · 1 min · jiezi

关于springboot:关于Docker安装和部署项目

DockerDocker装置装置依赖包 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 · 设置阿里云镜像源 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo · 装置 Docker-CE sudo yum install docker-ce装置docker-compose curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-composedocker-compose -versionGUI治理 这里举荐应用 Portainer 作为容器的 GUI 治理计划。 官网地址:https://portainer.io/install.... 装置命令: docker volume create portainer_datadocker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer拜访你的 IP:9000 即可进入容器治理页面。 Docker部署SpringBoot我的项目Dockerfile # 该镜像须要依赖的根底镜像FROM java:8# 将当前目录下的jar包复制到docker容器的/目录下ADD mall-tiny-docker-file-0.0.1-SNAPSHOT.jar /mall-tiny-docker-file.jar# 运行过程中创立一个mall-tiny-docker-file.jar文件RUN bash -c 'touch /mall-tiny-docker-file.jar'# 申明服务运行在8080端口EXPOSE 8080# 指定docker容器启动时运行jar包ENTRYPOINT ["java", "-jar","/mall-tiny-docker-file.jar"]# 指定维护者的名字MAINTAINER gyt将利用jar包及Dockerfile文件上传到linux服务器 ...

August 24, 2020 · 3 min · jiezi

关于springboot:扑街Spring-boot-admin-中的-httptrace-怎么没了

前言近日,收到群友反馈 Spring boot admin 中的 httptrace(http跟踪)没了,笔者复查了一下果然是没有了。 Spring boot admin 中的 http跟踪 会展现最近服务申请的申请,并展现申请的火焰图。如下图: 排查我在收到此问题时第一工夫去查看了 Spring boot admin 的代码,发现 httptrace 性能是存在的。 而后我在 Spring boot github 搜寻到了这条 issues:默认状况下禁用 management.trace.http 咱们能够看到在 Spring boot 2.0.0 M4 中去掉了默认注入的 InMemoryHttpTraceRepository Bean。 题外,大家遇到一些版本变动的问题,也能够去 Spring-boot、Spring cloud Github 的 issues 中搜寻。 论断Spring boot 2.2.x 正式版开始,不再默认开启 InMemoryHttpTraceRepository,所以导致了这个问题。 对于此问题,官网倡议采纳第三方组件来进行 httptrace 的收集,详见:激励应用第三方跟踪和可察看性解决方案,而不是实现本人的HttpTraceRepositroy。 下图为笔者采纳 prometheus 收集并展现到 Grafana 的示例。 关注咱们 扫描下面二维码,更多精彩内容每天举荐!

August 24, 2020 · 1 min · jiezi

关于springboot:Spring-Boot-240-新特性-ConfigurationClassPostProcessor-的非反射访问

从AnnotationConfigApplicationContext来看如何开始解析解析spring上下文。如果ConfigurationClassPostProcessor已被实例化提供能够间接非反射性的设置MetadataReaderFactory,代替应用PropertyValue,

August 24, 2020 · 1 min · jiezi

关于springboot:个人学习系列-Spring-Boot整合Jooq

之前应用的都是Spring Boot + Mybatis或者Hibernate进行数据库相干的开发,可是这些框架对于联表查问等又不是很敌对,最近发现了一个Jooq框架,据说很好用。。。搭建Spring Boot我的项目这个搭建形式我也就不在赘述了,不可能不会的吧? pom.xml文件<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jooq</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--jooq 须要的meta和生成代码的codegen包 这里留神查看spring-boot-starter-jooq 中的jooq是什么版本--> <dependency> <groupId>org.jooq</groupId> <artifactId>jooq-meta</artifactId> <version>3.13.4</version> </dependency> <dependency> <groupId>org.jooq</groupId> <artifactId>jooq-codegen</artifactId> <version>3.13.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- 代码生成器插件 --> <plugin> <groupId>org.jooq</groupId> <artifactId>jooq-codegen-maven</artifactId> <version>3.13.4</version> <configuration> <!-- 配置jdbc驱动连贯 --> <jdbc> <driver>com.mysql.cj.jdbc.Driver</driver> <url>jdbc:mysql://IP地址:3306/jooq?serverTimezone=GMT%2B8</url> <user>用户名</user> <password>明码</password> </jdbc> <generator> <database> <!-- 生成蕴含,*示意蕴含所有内容 --> <includes>.*</includes> <!-- 数据库名 --> <inputSchema>jooq</inputSchema> </database> <target> <!-- 生成的代码所在的包构造 --> <packageName>xyz.zhouzhaodong.jooq.dao</packageName> <!-- 生成的代码寄存门路,默认会以src同目录开始 --> <directory>/src/main/java</directory> </target> </generator> </configuration> </plugin> </plugins> </build>1. 代码生成模块整合进pom.xml外面外面蕴含了代码生成模块,能够在maven外面一键生成代码,这里须要留神的是,每次生成代码会笼罩之前的代码,也就是每次都是依据数据库生成最新的代码。 ...

August 24, 2020 · 3 min · jiezi

关于springboot:JSON-path-expectedentity-but-wasparams

前言人不知;鬼不觉假期就完结了,感觉在家的效率比在学校差太多,在学校晚睡,然而能早起,在家想早起是不可能的了,在家有着各种事件的影响,在学校就没有太多影响,回到学校还是很兴奋的。在本周学习的过程中遇到了这样的问题: java.lang.AssertionError: JSON path "$.menus" expected:<[club.yunzhi.exam.entity.Menu@5e54c34b]> but was:<{id=-5936975678746039928, name=CgIV, deleted=false, url=1Dzo, roleName=71qs}>Expected :[club.yunzhi.exam.entity.Menu@5e54c34b]Actual :{id=-5936975678746039928, name=CgIV, deleted=false, url=1Dzo, roleName=71qs}解决本问题呈现在后盾C层数据断言的测试中,代码如下: @Test void getRoleById() throws Exception{ Long id = new Random().nextLong(); Role role = new Role(); Set<Menu> menus = new HashSet<>(); Menu menu = new Menu(); menu.setId(new Random().nextLong()); menu.setName(new RandomString().make(4)); menu.setRoleName(new RandomString().make(4)); menu.setUrl(new RandomString().make(4)); menus.add(menu); role.setId(id); role.setName(RandomString.make(4)); role.setMenus(menus); Mockito.doReturn(role).when(this.roleService).getRoleById(Mockito.eq(id)); String url = this.url + "/" + id.toString(); System.out.println(MockMvcResultMatchers.jsonPath("$.menus")); System.out.println(role.getMenus()); this.mockMvc.perform(MockMvcRequestBuilders.get(url)) .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(role.getId())) .andExpect(MockMvcResultMatchers.jsonPath("$.name").value(role.getName())) .andExpect(MockMvcResultMatchers.jsonPath("$.menus").value(role.getMenus())); }而后起初是在Debug模式下进行察看:原本还想着在ResultMatchers离面看一下参数,怎奈外面啥也没有。而后再瞅一下报错信息:冀望的事一个实体数组,实际上却是实体对象,而后换了一种思路: ...

August 22, 2020 · 1 min · jiezi

关于springboot:Multi-Module-Spring-Boot集成测试使用JaCoCo生成测试覆盖率

个别的SpringBoot我的项目会由多Module组成,每个Module为不同的功能模块。我的项目启动时,多个Module提供不同的服务,独特反对了本我的项目所提供的服务。若采纳启动SpringBoot的形式进行多Module集成测试,个别test case会放在SpringApplication类所在的Module中,该Module个别仅提供了服务的入口,并无太多理论业务性能「简略来说,业务代码都不在这个Module中」。本文探讨运行集成测试,对多Module测试覆盖率合并统计的办法。 我的项目构造本文所述的我的项目具备如下构造: - pom.xml- subModule 1- - pom.xml- subModule 2- - pom.xmlRoot pom.xml治理我的项目公共Maven配置,subModule 1为利用入口,SpringApplication类也在其中,SpringBoot也在此Module中启动;subModule 2为业务功能模块,提供Service服务。 抉择JaCoCo个别测试覆盖率统计工具,独自在Module内执行test case,并别离为每个Module创立覆盖率报告,没有跨Module覆盖率的内置反对,也没有多个Module的合并报告。依据这篇文章Java覆盖率工具jacoco,Cobertura可知,JaCoCo有很多劣势,根本成为了目前惟一可用的工具,依据JaCoCo官网文档MavenMultiModule所述,JaCoCo 0.7.7版实现了新的Maven Goal jacoco:report-aggregate 。所以本文就基于以上材料,钻研并生成Maven多Module覆盖率汇总文档。 应用JaCoCo生成测试覆盖率文档因为官网只是强调实现了该性能,并未给出最佳实际,再次通过搜寻材料,发现了这篇 StackOverflow 回复给出了最佳实际,按其中的批示操作即可: 在根 pom.xml 中增加 jacoco-maven-plugin:<?xml version="1.0" encoding="UTF-8"?><project> <dependencyManagement> <dependencies> <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.4</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.4</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>在启动SpringBoot的子Module中,增加如下构建配置即可,不要忘了应用maven-surefire-plugin插件对test case进行治理。<project> <dependencies> <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.4</version> <executions> <execution> <id>report-aggregate</id> <phase>verify</phase> <goals> <goal>report-aggregate</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>配置好后,只须要在利用根目录下「Root pom.xml所在的目录下」,执行Maven指令 mvn verify,之后在SpringBoot子Module中,关上target/site/jacoco-aggregate/index.html,即可在浏览器中查看具体的测试覆盖率报告了。覆盖率报告示例如下: ...

August 22, 2020 · 1 min · jiezi

关于springboot:Spring-Boot快速入门之十二异常处理

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_exception_handling.htm 对于企业应用而言,在 API 中解决好异样和谬误是至关重要的。本文将带你学习如果在 Spring Boot 中解决异样。 在学习异样解决前让咱们先来了解上面的注解: Controller Advice@ControllerAdvice 注解用于解决全局异样。 Exception Handler@ExceptionHandler 注解是用于解决指定的异样并向客户端发送一个自定义的响应。 能够应用上面的代码来创立 @ControllerAdvice 类以解决全局异样: package com.tutorialspoint.demo.exception; import org.springframework.web.bind.annotation.ControllerAdvice; @ControllerAdvice public class ProductExceptionController { } 定义一个继承 RuntimeException 的类。 package com.tutorialspoint.demo.exception; public class ProductNotfoundException extends RuntimeException { private static final long serialVersionUID = 1L; } 如下所示,能够定义 @ExceptionHandler 办法来解决异样。这个办法该当被用于编写 Controller Advice 类文件。 @ExceptionHandler(value = ProductNotfoundException.class) public ResponseEntity<Object> exception(ProductNotfoundException exception) { } 当初,应用以下代码来抛出来自 API 的异样: @RequestMapping(value = "/products/{id}", method = RequestMethod.PUT) ...

August 22, 2020 · 3 min · jiezi

关于springboot:Spring三级缓存和循环依赖

1. 循环依赖什么是依赖注入?假如有两个类A和B,A在实例化的时候须要B的实例,而B在实例化时又须要A的实例,在类的实例化过程就陷入死循环。这也就是传统逻辑上的,“到底是先有鸡,还是先有蛋”的问题?上面举一个例子,定义了两个类Type和Org: // Org.java@Data@Componentpublic class Org { private final Role role; public Org(Role role) { this.role = role; }}// Role.java@Data@Componentpublic class Role { private final Org org; public Role(Org org) { this.org = org; }}这是spring中典型的结构器注入形式,其实也代表了一般非spring bean之间,相互依赖时的实例化过程,但后果在运行的时候间接报循环依赖的谬误: ***************************APPLICATION FAILED TO START***************************Description:The dependencies of some of the beans in the application context form a cycle: demoController (field private pers.kerry.exercise.springexercise.pojo.Org pers.kerry.exercise.springexercise.controller.DemoController.org)┌─────┐| org defined in file [/Users/kerry/code/idea/spring-exercise/target/classes/pers/kerry/exercise/springexercise/pojo/Org.class]↑ ↓| role defined in file [/Users/kerry/code/idea/spring-exercise/target/classes/pers/kerry/exercise/springexercise/pojo/Role.class]└─────┘而如果咱们改一下代码,把结构器注入形式改成基于属性的注入(@Autowired、@Resouce),奇怪的是不报错了,而且相互依赖的两个bean 都实例化胜利了。阐明spring框架有解决循环依赖的问题,咱们理解spring解决循环依赖的过程,其实有助于进一步理解spring 中 bean的流动过程。 ...

August 21, 2020 · 4 min · jiezi

关于springboot:SpringBean的注册与注入方式

1、背景IoC(Inversion of Control)管制反转,IoC是一种通过形容来生成或获取对象的技术。每一个须要治理的对象称为Spring Bean,而Spring治理这些Bean的容器称为Spring IoC容器,也就是咱们所说的Spring应用程序上下文ApplicationContext。 IOC容器负责实例化、定位、配置应用程序中的对象及建设这些对象间的依赖。交由Spring容器对立进行治理,从而实现松耦合。 容器启动,创立和初始化IoC 容器扫描包下所有class,通过反射解析class类的信息,包含注解信息基于反射实例的对象,对其进行封装将实例的对象放入汇合中保留能够通过getBean获取汇合中对象2、@SpringBootApplication@SpringBootApplication开启了Spring的组件扫描和SpringBoot主动配置性能。实际上它是一个复合注解,蕴含3个重要的注解: @SpringBootConfiguration、@ComponentScan、@EnableAutoConfiguration。 SpringBoot晚期的版本中,须要在入口类同时增加这3个注解,但从SpringBoot1.2.0开始,只有在入口类增加@SpringBootApplication注解即可。咱们如果想了解它的含意,能够从通过剖析这3个注解开始。 2.1、@SpringBootConfiguration@SpringBootConfiguration 是对 @Configuration 的简略封装,二者性能上没有太大差别。后者咱们比拟相熟,所以 @SpringBootConfiguration 能够了解为配置类的注解,会将以后类内申明的一个或多个以@Bean注解标记的办法的实例纳入到spring容器中。 2.2、@ComponentScan@ComponentScan次要就是定义扫描的门路,从中找出标识了须要拆卸的类主动拆卸到spring的bean容器中。默认扫描门路是以后门路,因为启动类是在我的项目的根门路,所以启动类中的该注解,默认扫描的以后我的项目门路。 那么怎么找出须要拆卸的类呢?咱们晓得失常装载类,是要在配置类下注册Bean的。然而咱们日常应用的@Controller、@Service、@Repository、@Component、@Configuration却能够主动装载,就是因为@ComponentScan这个注解。@Component是个非凡的注解,它能够被@ComponentScan扫描装载,如果查看@Controller、@Service、@Repository、@Configuration等注解的源码就会发现,它们都继承@Component,因而同样也能够主动被扫描装载进容器中。 @ComponentScan注解的罕用属性包含:value/basePackages:定义扫描的门路。includeFilters:退出扫描门路下,没有继承@Component注解的类退出spring容器。excludeFilters:过滤出不必退出spring容器的类。2.3、@EnableAutoConfiguration我的项目开发时,常常通过maven等形式引入第三方jar包,那么也同样冀望可能将第三方jar包中的Bean也加载进以后我的项目的Bean容器中。后面说过@ComponentScan能够将定义扫描门路下的Bean装载进容器中,因而能够手动的在@ComponentScan注解的value属性中,填上所有第三方jar包的扫描门路。实践上是这样的,但应该没有人这么干吧?一个我的项目依赖几十个jar包,那要配置多少扫描门路? 因而个别有另外的两种办法来实现需求,个别咱们开发一个供调用的jar包利用(如starter),次要依靠自身的配置类来注入Bean(@Configuration+@Bean 或 @ComponentScan+@Component),因而只有保障第三方利用的配置类能加载进以后的Bean容器即可。 @Import 和 spring.factories第三方利用,定义一个注解(个别是Enable结尾),通过 @Import 注解注入配置类。并且以后我的项目的配置类(倡议启动类)中加上该注解。//配置类@Configuration@EnableConfigurationProperties({ SecurityProperty.class})@ComponentScan(basePackages = {"com.smec.mpaas.unicorn"})public class UnicornAutoConfig { }//注解@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Import({UnicornAutoConfig.class})public @interface EnableUnicorn {}在第三方利用/META-INF 目录下创立 spring.factories 文件,并定义须要加载的配置类门路。以后我的项目的 @EnableAutoConfiguration// mybatis 的 spring.factoriesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration咱们重点谈谈第二种,因为用到了@EnableAutoConfiguration,注解的定义如下: @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class[] exclude() default {}; String[] excludeName() default {};}@EnableAutoConfiguration实现的关键在于引入了AutoConfigurationImportSelector,其外围逻辑为selectImports办法,借助AutoConfigurationImportSelector,它能够帮忙SpringBoot利用将所有符合条件的@Configuration配置都加载到以后SpringBoot创立并应用的IoC容器。 xxxAutoConfiguration条件注解当springboot扫描到@EnableAutoConfiguration注解时则会将spring-boot-autoconfigure.jar/META-INF/spring.factories文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的value里的所有xxxConfiguration类加载到IOC容器中。spring.factories文件里每一个xxxAutoConfiguration文件个别都会有上面的条件注解: @ConditionalOnClass : classpath中存在该类时起效@ConditionalOnMissingClass : classpath中不存在该类时起效@ConditionalOnBean : DI容器中存在该类型Bean时起效@ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效@ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效@ConditionalOnExpression : SpEL表达式后果为true时@ConditionalOnProperty : 参数设置或者值统一时起效@ConditionalOnResource : 指定的文件存在时起效@ConditionalOnJndi : 指定的JNDI存在时起效@ConditionalOnJava : 指定的Java版本存在时起效@ConditionalOnWebApplication : Web应用环境下起效@ConditionalOnNotWebApplication : 非Web应用环境下起效AutoConfigurationImportSelector类的逻辑SpringBoot中EnableAutoConfiguration实现的关键在于引入了AutoConfigurationImportSelector,其外围逻辑为selectImports办法,逻辑大抵如下: ...

August 21, 2020 · 2 min · jiezi

关于springboot:SpringBean的生命周期

1. 前言最后接触java的接口服务是servlet,最根底要把握的就是servlet的生命周期。当初都是基于springboot开发后盾接口,spring框架的复杂度远远高于原始的servlet,弄清楚spring中bean的生命周期,有利于咱们对其框架的熟练掌握。 2. spring容器加载springboot的启动类中,都会执行SpringApplication.run办法。在创立上下文环境之后,最外围的办法就是refreshContext,对上下文环境进行初始化操作,本段就着重阐明这一过程。 2.1. refreshContext全过程 @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { /** * 筹备环境 * 1. 记录容器的启动工夫startupDate,标记容器为激活 * 2. 初始化上下文环境如文件门路信息 * 3. 验证必填属性是否填写 */ prepareRefresh(); /** * 通知子类去刷新beanFactory * 这步实现后配置文件就解析成一个个beanDefination,注册到BeanFactory(然而未被初始化,仅将信息写到了beanDefination的map中) */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); /** * 设置beanFactory类加载器,增加多个beanPostProcesser */ prepareBeanFactory(beanFactory); try { /** * 容许子类上下文中对beanFactory做前期解决 */ postProcessBeanFactory(beanFactory); /** * 执行 context 中注册的 BeanFactoryPostProcessor中的postProcessBeanFactory() 办法 * 1. BeanFactoryPostProcessor 是 bean 属性解决容器。即治理 bean工厂中的BeanDefinition * 2. BeanDefinition在 spring mvc中就是xml文件中对应的bean标签(留神,是标签,而不是实在的 java bean) */ invokeBeanFactoryPostProcessors(beanFactory); /** * 注册 BeanPostProcessor 的实现类 * 1. BeanPostProcessor接口蕴含两个办法:postProcessBeforeInitialization 和 postProcessAfterInitialization * 2. 这里只是注册,两个办法理论别离在 Bean初始化之前和初始化之后失去执行 */ registerBeanPostProcessors(beanFactory); /** * 初始化ApplicationContext的MessageSource,MessageSource是国际化相干的接口 */ initMessageSource(); /** * 初始化ApplicationContext事件播送器 */ initApplicationEventMulticaster(); // 初始化子类非凡bean(钩子办法) onRefresh(); /** * 注册事件监听器 */ registerListeners(); /** * 初始化所有的单例java bean(不蕴含懒加载的类) */ finishBeanFactoryInitialization(beanFactory); /** * 播送事件,ApplicationContext初始化实现 */ finishRefresh(); } catch (BeansException ex) { .................... } } }2.2. BeanDefinitionBeanDefinition 是 spring bean 的建模对象,即把一个bean实例化进去的模型对象。有人会问把一个bean实例化进去有Class就行了啊,Class也就是咱们通常说的类对象,就是一个一般对象的建模对象,那么为什么spring不能用Class来建设bean呢?很简略,因为Class无奈实现bean的形象,比方bean的作用域,bean的注入模型,bean是否是懒加载等等信息,Class是无奈形象进去的,故而须要一个BeanDefinition类来形象这些信息,以便于spring可能完满的实例化一个bean。 ...

August 21, 2020 · 4 min · jiezi

关于springboot:Spring-Boot快速入门之十一构建-RESTful-Web-服务

【注】本文译自:  https://www.tutorialspoint.com/spring_boot/spring_boot_building_restful_web_services.htm Spring Boot 提供了构建企业应用中 RESTful Web 服务的极佳反对。本文为你详解如何应用 Spring Boot 构建 RESTful web 服务。 留神:要构建 RESTful Web 服务,咱们须要在构建配置文件中加上 Spring Boot Starter Web 依赖。 对于 Maven 用户,应用以下的代码在 pom.xml 文件中退出依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 对于 Gradle 用户,应用以下的代码在 build.gradle 文件中退出依赖: compile('org.springframework.boot:spring-boot-starter-web') 残缺的构建配置文件 Maven build – pom.xml 如下: <?xml version = "1.0" encoding = "UTF-8"?> <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint</groupId> <artifactId>demo</artifactId> ...

August 20, 2020 · 4 min · jiezi

关于springboot:SpringSecurity权限管理系统实战一项目简介和开发环境准备

目录SpringSecurity权限管理系统实战—一、我的项目简介和开发环境筹备SpringSecurity权限管理系统实战—二、日志、接口文档等实现SpringSecurity权限管理系统实战—三、次要页面及接口实现SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)SpringSecurity权限管理系统实战—五、整合SpringSecurity(下)SpringSecurity权限管理系统实战—六、SpringSecurity整合jwtSpringSecurity权限管理系统实战—七、解决一些问题SpringSecurity权限管理系统实战—八、AOP 记录用户日志、异样日志 前言博主的文笔有些差,大家多担待 一、简介 在企业应用中,认证和受权是十分重要的一部分内容,业界最闻名的两个框架就是赫赫有名的 Shiro和Spring Security。本次我选取的是和SpringBoot更好兼容的SpringSecurity。 二、什么是RBAC RBAC是Role Based Access Control的缩写,是基于角色的访问控制。个别都是分为用户(user), 角色(role),权限(permission)三个实体,角色(role)和权限(permission)是多对多的 关系,用户(user)和角色(role)也是多对多的关系。用户(user)和权限(permission) 之间没有间接的关系,都是通过角色作为代理,能力获取到用户(user)领有的权限。 以下是RBAC0的模型 具体解释见 三、零碎性能用户治理:提供用户的相干配置角色治理:对权限与菜单进行调配菜单治理:已实现菜单动静路由,后端可配置化,反对多级菜单字典治理:可保护罕用一些固定的数据系统日志:记录用户操作日志与异样日志SQL监控:采纳druid 监控数据库拜访性能代码生成:高灵便度生成前后端代码,缩小大量反复的工作工作接口治理:不便对立查看治理接口因为本零碎是边开发写此文档的,所以可能上述的性能在后续的开发中会有删改。 四、环境搭建本次零碎非前后端拆散我的项目,基于SpringBoot+Layui,后盾模板选用的是Pear Admin Layui (我目前见过最丑陋的layui后盾模板,放张图片让大家感受一下) 数据库设计 目前先这样,之后还会扩大。 在idea中新建SpringBoot我的项目,导入所需依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--这里须要先把SpringSecurity登记--><!-- <dependency>--><!-- <groupId>org.springframework.boot</groupId>--><!-- <artifactId>spring-boot-starter-security</artifactId>--><!-- </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <!--swagger ui--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.7.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> 在我的项目中把架构搭好,创立对应数据库表的eneity、dao、service、controller,非常简单不想占用篇幅。须要留神的就是实体类中的create_time,和update_time,因为这两个和id是在多张表中都有呈现,所以咱们能够把它们抽离进去,有须要的实体类间接继承就能够了 ...

August 19, 2020 · 4 min · jiezi

关于springboot:Spring-Security-OAuth2-之授权码模式

受权码模式应用是最宽泛,而且大多数互联网站点都应用了此模式,如第三方应用QQ和微信登录。 一、Spring Security OAuth2表构造 受权码模式用到了四张表,这里贴上Oracle版本的脚本。 -- OAUTH2.0 须要的4张表CREATE TABLE OAUTH_CLIENT_DETAILS( CLIENT_ID VARCHAR2(128) NOT NULL CONSTRAINT PK_OAUTH_CLIENT_DETAILS PRIMARY KEY, RESOURCE_IDS VARCHAR2(128) DEFAULT NULL, CLIENT_SECRET VARCHAR2(128) DEFAULT NULL, SCOPE VARCHAR2(128) DEFAULT NULL, AUTHORIZED_GRANT_TYPES VARCHAR2(128) DEFAULT NULL, WEB_SERVER_REDIRECT_URI VARCHAR2(1024) DEFAULT NULL, AUTHORITIES VARCHAR2(128) DEFAULT NULL, ACCESS_TOKEN_VALIDITY NUMBER(11) DEFAULT NULL, REFRESH_TOKEN_VALIDITY NUMBER(11) DEFAULT NULL, ADDITIONAL_INFORMATION VARCHAR2(4000) DEFAULT NULL, AUTOAPPROVE VARCHAR2(128) DEFAULT NULL);COMMENT ON TABLE OAUTH_CLIENT_DETAILS IS '利用表';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.CLIENT_ID IS '利用ID';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.RESOURCE_IDS IS '受权资源ID汇合';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.CLIENT_SECRET IS '利用密钥';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.SCOPE IS '受权作用域';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.AUTHORIZED_GRANT_TYPES IS '受权容许类型';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.WEB_SERVER_REDIRECT_URI IS '受权回调地址';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.AUTHORITIES IS '领有权限汇合';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.ACCESS_TOKEN_VALIDITY IS 'ACCESS_TOKEN有效期(秒)';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.REFRESH_TOKEN_VALIDITY IS 'REFRESH_TOKEN有效期(秒)';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.ADDITIONAL_INFORMATION IS '附加信息(预留)';COMMENT ON COLUMN OAUTH_CLIENT_DETAILS.AUTOAPPROVE IS '主动批准受权(TRUE,FALSE,READ,WRITE)';CREATE TABLE OAUTH_CODE( CODE VARCHAR2(128) DEFAULT NULL, AUTHENTICATION BLOB);CREATE INDEX IX_OAUTH_CODE_CODE ON OAUTH_CODE (CODE);COMMENT ON TABLE OAUTH_CODE IS '受权码表';COMMENT ON COLUMN OAUTH_CODE.CODE IS '受权码';COMMENT ON COLUMN OAUTH_CODE.AUTHENTICATION IS '身份验证信息';CREATE TABLE OAUTH_ACCESS_TOKEN( AUTHENTICATION_ID VARCHAR2(128) NOT NULL CONSTRAINT PK_OAUTH_ACCESS_TOKEN PRIMARY KEY, TOKEN_ID VARCHAR2(128) DEFAULT NULL, TOKEN BLOB, USER_NAME VARCHAR2(128) DEFAULT NULL, CLIENT_ID VARCHAR2(128) DEFAULT NULL, AUTHENTICATION BLOB, REFRESH_TOKEN VARCHAR2(128) DEFAULT NULL);CREATE INDEX IX_OAT_TOKEN_ID ON OAUTH_ACCESS_TOKEN (TOKEN_ID);CREATE INDEX IX_OAT_USER_NAME ON OAUTH_ACCESS_TOKEN (USER_NAME);CREATE INDEX IX_OAT_CLIENT_ID ON OAUTH_ACCESS_TOKEN (CLIENT_ID);CREATE INDEX IX_OAT_REFRESH_TOKEN ON OAUTH_ACCESS_TOKEN (REFRESH_TOKEN);COMMENT ON TABLE OAUTH_ACCESS_TOKEN IS '受权TOKEN表';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.AUTHENTICATION_ID IS '身份验证ID';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.TOKEN_ID IS 'ACCESS_TOKEN加密值';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.TOKEN IS 'ACCESS_TOKEN实在值';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.USER_NAME IS '用户名';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.CLIENT_ID IS '利用ID';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.AUTHENTICATION IS '身份验证信息';COMMENT ON COLUMN OAUTH_ACCESS_TOKEN.REFRESH_TOKEN IS 'REFRESH_TOKEN加密值';CREATE TABLE OAUTH_REFRESH_TOKEN( TOKEN_ID VARCHAR2(128) DEFAULT NULL, TOKEN BLOB, AUTHENTICATION BLOB);CREATE INDEX IX_ORT_TOKEN_ID ON OAUTH_REFRESH_TOKEN (TOKEN_ID);COMMENT ON TABLE OAUTH_REFRESH_TOKEN IS '刷新TOKEN表';COMMENT ON COLUMN OAUTH_REFRESH_TOKEN.TOKEN_ID IS 'ACCESS_TOKEN加密值';COMMENT ON COLUMN OAUTH_REFRESH_TOKEN.TOKEN IS 'ACCESS_TOKEN实在值';COMMENT ON COLUMN OAUTH_REFRESH_TOKEN.AUTHENTICATION IS '身份验证信息';二、服务端实现 ...

August 17, 2020 · 22 min · jiezi

关于springboot:RestController

在我的项目中写管制层时,咱们通常会用@Controller注解来对于管制层类进行形容, 而当类中的办法须要返回数据而不是页面时,咱们会在办法上用@ResponseBody注解形容, 而当类中所有办法都要返回数据时,咱们就能够将@ResponseBody注解提取进去,间接形容在类上, 这样咱们管制层类上就既有@Controller注解也有@ResponseBody注解,这是咱们就能够将两个注解写为一个注解@RestController @RestController=@Controller+@ResponseBody.

August 16, 2020 · 1 min · jiezi

关于springboot:RestController

在我的项目中写管制层时,咱们通常会用@Controller注解来对于管制层类进行形容, 而当类中的办法须要返回数据而不是页面时,咱们会在办法上用@ResponseBody注解形容, 而当类中所有办法都要返回数据时,咱们就能够将@ResponseBody注解提取进去,间接形容在类上, 这样咱们管制层类上就既有@Controller注解也有@ResponseBody注解,这是咱们就能够将两个注解写为一个注解@RestController @RestController=@Controller+@ResponseBody.

August 16, 2020 · 1 min · jiezi

关于springboot:springboot-yml文件

在springboot的应用中,通过IDE创立springboot我的项目时,会间接生成一个配置文件application.properties,咱们能够在这个文件中实现对于我的项目的简略配置,而除了properties文件外,咱们还能够应用yml格局的文件,然而留神properties文件的优先级>yml文件的优先级. yml文件在编写时,如果你的名称为application.yml,编写会有注解,并出现小叶子的图案. yml编写时肯定要留神行与行之间的缩进(树形关系),以及属性名与属性值之间的空格. 配置mybatis如下:

August 16, 2020 · 1 min · jiezi

关于springboot:springboot整合Kafka使用zookeeper做服务治理

一.springboot主动配置形式整合kafka: springboot提供主动配置整合kafka的形式,须要做一下步骤: 1. 引入kafka依赖包: <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.2.7.RELEASE</version> </dependency>2.在springboot配置中退出kafka相干配置,springboot启动时候会主动加载这些配置,实现链接kafka,创立producer,consumer等。 spring: kafka: # kafka服务地址 bootstrap-servers: 127.0.0.1:9092 # 消费者配置 consumer: bootstrap-servers: 127.0.0.1:9092 group-id: myGroup enable-auto-commit: true auto-offset-reset: earliest auto-commit-interval: 1000 max-poll-records: 10 # 生产者配置 producer: retries: 5 batch-size: 16384 buffer-memory: 33554432 acks: 13.音讯发送端: @Componentpublic class MqProviderImpl{ @Autowired private KafkaTemplate<String, String> kafkaTemplate; @Override public void sendSkMessage(String message, Properties properties) { // 发送音讯,注册一个回调事件 ListenableFuture<SendResult<String, String>> futureMessage = KafkaConfig.kafkaTemplateStatic.send("test_topic", message); futureMessage.addCallback(new ListenableFutureCallback<SendResult<String, String>>(){ @Override public void onSuccess(SendResult<String, String> sendResult) { log.info(" rev "+sendResult.getProducerRecord().value()); } @Override public void onFailure(Throwable ex) { log.error(" error "+ex.getMessage()); } }); }}4.音讯生产端: ...

August 16, 2020 · 2 min · jiezi

关于springboot:在Spring-boot中使用Spring-AOP

AOP(Aspect Oriented Programming,面向切面编程)是通过预编译形式和运行期动静代理实现程序性能的对立保护的一种技术。利用AOP能够对业务逻辑的各个局部进行隔离,从而使得业务逻辑各局部之间的耦合度升高,进步程序的可重用性,同时进步了开发的效率。 在Spring AOP中业务逻辑仅仅只关注业务自身,将日志记录、性能统计、安全控制、事务处理、异样解决等代码从业务逻辑代码中划分进去,从而在扭转这些行为的时候不影响业务逻辑的代码。 相干注解介绍: 注解作用@Aspect把以后类标识为一个切面@PointcutPointcut是织入Advice的触发条件。每个Pointcut的定义包含2局部,一是表达式,二是办法签名。办法签名必须是public及void型。能够将Pointcut中的办法看作是一个被Advice援用的助记符,因为表达式不直观,因而咱们能够通过办法签名的形式为此表达式命名。因而Pointcut中的办法只须要办法签名,而不须要在办法体内编写理论代码。@Around盘绕加强,指标办法执行前后别离执行一些代码@AfterReturning返回加强,指标办法失常执行结束时执行@Before前置加强,指标办法执行之前执行@AfterThrowing异样抛出加强,指标办法产生异样的时候执行@After后置加强,不论是抛出异样或者失常退出都会执行https://www.cnblogs.com/wangdahui/p/13048222.html对于同一个连接点,可能同时存在多个切面,在组织切面时,能够通过@Order注解指定切面的执行程序。

August 16, 2020 · 1 min · jiezi

关于springboot:在Spring-boot中使用Spring-AOP

AOP(Aspect Oriented Programming,面向切面编程)是通过预编译形式和运行期动静代理实现程序性能的对立保护的一种技术。利用AOP能够对业务逻辑的各个局部进行隔离,从而使得业务逻辑各局部之间的耦合度升高,进步程序的可重用性,同时进步了开发的效率。 在Spring AOP中业务逻辑仅仅只关注业务自身,将日志记录、性能统计、安全控制、事务处理、异样解决等代码从业务逻辑代码中划分进去,从而在扭转这些行为的时候不影响业务逻辑的代码。 相干注解介绍: 注解作用@Aspect把以后类标识为一个切面@PointcutPointcut是织入Advice的触发条件。每个Pointcut的定义包含2局部,一是表达式,二是办法签名。办法签名必须是public及void型。能够将Pointcut中的办法看作是一个被Advice援用的助记符,因为表达式不直观,因而咱们能够通过办法签名的形式为此表达式命名。因而Pointcut中的办法只须要办法签名,而不须要在办法体内编写理论代码。@Around盘绕加强,指标办法执行前后别离执行一些代码@AfterReturning返回加强,指标办法失常执行结束时执行@Before前置加强,指标办法执行之前执行@AfterThrowing异样抛出加强,指标办法产生异样的时候执行@After后置加强,不论是抛出异样或者失常退出都会执行https://www.cnblogs.com/wangdahui/p/13048222.html

August 16, 2020 · 1 min · jiezi

关于springboot:用Spring-Boot-Admin来监控我们的微服务

【转载请注明出处】:https://blog.csdn.net/huahao1989/article/details/108039738 1.概述Spring Boot Admin是一个Web应用程序,用于治理和监督Spring Boot应用程序。每个应用程序都被视为客户端,并注册到治理服务器。底层能力是由Spring Boot Actuator端点提供的。 在本文中,咱们将介绍配置Spring Boot Admin服务器的步骤以及应用程序如何集成客户端。 2.治理服务器配置因为Spring Boot Admin Server能够作为servlet或webflux利用程序运行,依据须要,抉择一种并增加相应的Spring Boot Starter。在此示例中,咱们应用Servlet Web Starter。首先,创立一个简略的Spring Boot Web应用程序,并增加以下Maven依赖项: <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> <version>2.2.3</version></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>之后,@ EnableAdminServer将可用,因而咱们将其增加到主类中,如下例所示: @EnableAdminServer@SpringBootApplicationpublic class SpringBootAdminServerApplication { public static void main(String[] args) { SpringApplication.run(SpringBootAdminServerApplication.class, args); }}至此,服务端就配置完了。 3.设置客户端要在Spring Boot Admin Server服务器上注册应用程序,能够包含Spring Boot Admin客户端或应用Spring Cloud Discovery(例如Eureka,Consul等)。 上面的例子应用Spring Boot Admin客户端进行注册,为了爱护端点,还须要增加spring-boot-starter-security,增加以下Maven依赖项: <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.2.3</version></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId></dependency>接下来,咱们须要配置客户端阐明治理服务器的URL。为此,只需增加以下属性: spring.boot.admin.client.url=http://localhost:8080从Spring Boot 2开始,默认状况下不公开运行状况和信息以外的端点,对于生产环境,应该认真抉择要公开的端点。 management.endpoints.web.exposure.include=*management.endpoint.health.show-details=always使执行器端点可拜访: @Configurationpublic static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll() .and().csrf().disable(); }}为了简洁起见,临时禁用安全性。 ...

August 16, 2020 · 2 min · jiezi

关于springboot:SpringCloud组件简述

SpringCloud 1.Eureka Zookeeper Consul 注册核心2.Feign Ribbon OpenFeign微服务间的调用,负载平衡3.Hystrix服务降级,服务熔断4.Zuul Gateway网关5.Config配置核心6.Bus音讯总线,刷新配置7.Stream音讯对立Api8.Sleuth服务链路追踪 SpringCloud Alibaba1.Nacos注册核心 + 配置核心2.Sentinel服务熔断 服务限流 服务降级3.Seata分布式事务 Demo:https://github.com/WillLiaowh/springcloud-learning2020

August 15, 2020 · 1 min · jiezi

关于springboot:Spring-Boot系列之读取配置

应用SpringBoot框架开发,读取配置是少不了的,那么你会读取配置吗?你会写配置吗?List?Map? 1 目标本节咱们要解决如下几个问题: 如何应用Spring Boot读取配置文件?有哪些形式?罕用的几种数据结构,如字符串、整数、List、Map,如何配置?如何读取?如何自定义配置文件的门路?2 读配置文件Spring Boot默认的配置文件有两种格局: application.properties 和 application.yml 。 查找程序是首先从application.properties 查找,如果找不到,再查找 application.yml。 优先级: application.properties > application.yml 。 2.1 应用 @Value 读取配置配置如下: erwin.name=冯文议erwin.age=20erwin.sex=男erwin.english-name=Erwin Fengerwin.birthday=1992/02/26erwin.like=movie,game,music,tea,travelerwin.visitedCities=巴中,揭阳,广州,从化,成都,三亚,上海,杭州,北京erwin.moreOther={myWeb:'https://fengwenyi.com',github:'https://github.com/fengwenyi'}代码如下: package com.fengwenyi.spring_boot_config_sample.config;import lombok.Data;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import java.util.*;/** * @author Erwin Feng * @since 2020/8/11 */@Data@Configurationpublic class ReadConfigByValue { @Value("${erwin.name}") private String name; @Value("${erwin.age}") private Integer age; @Value("${erwin.sex}") private String sex; @Value("${erwin.english-name}") private String englishName; @Value("${erwin.birthday}") private Date birthday; @Value("${erwin.like}") private List<String> likes; @Value("#{'${erwin.visitedCities}'.split(',')}") private List<String> visitedCities; @Value("#{${erwin.moreOther}}") private Map<String, String> moreOther; } ...

August 15, 2020 · 2 min · jiezi

关于springboot:Spring-Boot快速入门之十日志

【注】本文译自:  https://www.tutorialspoint.com/spring_boot/spring_boot_logging.htm Spring Boot 应用 Apache Commons logging 作为外部日志。Spring Boot 缺省配置提供对于 Java Util Logging, Log4j2 和 Logback 的反对。这样,咱们能够配置控制台或者文件日志。 如果应用 Spring Boot 启动器,Logback 会提供很好的日志反对。此外,Logback 对 Common Logging、Util Logging、Log4J 和 SLF4J 的反对也不错。 Log 格局缺省 Spring Boot 的日志格局如下图所示: 提供了以下信息: Date 和 Time 给出日志的日期和工夫Log level 显示 INFO, ERROR 或 WARNProcess ID用 --- 作为分隔符Thread name 在 方括号 [] 内Logger Name 显示源类名日志音讯控制台日志输入默认日志音讯会打印到控制台窗口。短少状况下,“INFO”, “ERROR” 和 “WARN” 日志音讯会在日志文件中打印。 如果要容许 debug 级别的日志,用命令行启动利用时加上 debug 标识,如下所示: ...

August 14, 2020 · 2 min · jiezi

关于springboot:SpringBoot如何设计优秀的后端接口

1 概述本篇文章以Spring Boot为根底,从以下三个方向讲述了如何设计一个优良的后端接口体系: 参数校验:波及Hibernate Validator的各种注解,疾速失败模式,分组,组序列以及自定义注解/Validator异样解决:波及ControllerAdvice/@RestControllerAdvice以及@ExceptionHandler数据响应:波及如何设计一个响应体以及如何包装响应体有了一个优良的后端接口体系,不仅有了标准,同时扩大新的接口也很容易,本文演示了如何从零一步步构建一个优良的后端接口体系。 2 新建工程关上相熟的IDEA,抉择依赖: 首先创立如下文件: TestController.java: @RestController@RequestMapping("/")@CrossOrigin(value = "http://localhost:3000")@RequiredArgsConstructor(onConstructor = @__(@Autowired))public class TestController { private final TestService service; @PostMapping("test") public String test(@RequestBody User user) { return service.test(user); }}应用了@RequiredArgsConstructor代替@Autowired,因为笔者应用Postwoman测试,因而须要加上跨域注解@CrossOrigin,默认3000端口(Postwoman端口)。 TestService.java: @Servicepublic class TestService { public String test(User user) { if(StringUtils.isEmpty(user.getEmail())) return "邮箱不能为空"; if(StringUtils.isEmpty(user.getPassword())) return "明码不能为空"; if(StringUtils.isEmpty(user.getPhone())) return "电话不能为空";// 长久化操作 return "success"; }}业务层首先进行了参数校验,这里省略了长久化操作。 User.java: @Datapublic class User { private String phone; private String password; private String email;}3 参数校验首先来看一下参数校验,下面的例子中在业务层实现参数校验,这是没有问题的,然而,还没进行业务操作就须要进行这么多的校验显然这不是很好,更好的做法是,应用Hibernate Validator。 ...

August 13, 2020 · 4 min · jiezi

关于springboot:SpringBoot入门

Spring Boot概述随着互联网的疾速倒退,企业当初更重视技术的开箱即用,更重视技术在生态圈中的深度交融,更重视轻量级的运维。 Spring Boot个性Spring Boot构建于Spring框架之上,基于疾速构建理念,有开箱即用,主动配置的个性 Spring Boot配置

August 12, 2020 · 1 min · jiezi

关于springboot:Spring-Boot快速入门之九应用属性

【注】本文译自: https://www.tutorialspoint.com/spring_boot/spring_boot_application_properties.htm 利用属性可能反对在不同环境中工作。本文将带你学习如何在 Spring Boot 利用中配置特定的属性。 命令行属性Spring Boot 利用将命令行属性转换为 Spring Boot 环境属性。命令行属性优先于其余属性源。Spring Boot 默认应用 8080 端口号启动 Tomcat。让咱们学习如何应用命令行属性扭转它。 第1步: 创立可执行 JAR 文件,应用命令 java –jar <JARFILE> 运行。 第2步: 如上面截屏的命令所示,利用命令行属性扭转 Spring Boot 利用的端口号: 留神: 你能够应用分隔符号 - 提供多个利用属性。 属性文件属性文件的作用在于,在不同环境中运行的利用应用单个属性文件配置多个属性。Spring Boot 中属性被配置在 application.properties 文件中,这个文件要在 classpath 门路中。 application.properties 文件位于 src/main/resources 目录。以下代码是 application.properties 文件的示例: server.port = 9090 spring.application.name = demoservice 要留神下面的代码指定 Spring Boot 利用 demoservice 启动的端口号为 9090。 YAML 文件Spring Boot 反对基于 YAML 的属性配置来运行利用。代之以 application.properties,咱们能够应用 application.yml 文件。这个 YAML 文件也该当在 classpath 门路下。application.yml 文件示例如下: ...

August 12, 2020 · 2 min · jiezi

关于springboot:Spring-Boot快速入门之八运行器

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_runners.htm 利用运行器和命令行运行器接口能够让你的代码在 Spring Boot 应该启动之后执行,你能够应用这些接口让利用启动之后立刻执行任何行为。本文为你细说详情。 利用运行器利用运行器是一个接口,用于在 Spring Boot 利用启动之后执行代码。上面的代码展现了如何在主类文件中实现利用运行器接口: package com.tutorialspoint.demo; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication implements ApplicationRunner { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(ApplicationArguments arg0) throws Exception { System.out.println("Hello World from Application Runner"); } } 如下所示,在控制台窗口中运行,能够看到在 Tomcat 启动之后打印出了 Hello World from Application Runner: 命令行运行器命令行运行器是一个接口,可用于在 Spring Boot 利用启动之后执行代码。上面的代码展现了如何在主类文件中实现命令行运行器接口: package com.tutorialspoint.demo; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; ...

August 11, 2020 · 1 min · jiezi

关于springboot:Spring-Boot快速入门之七Bean和依赖注入

【注】本文译自: https://www.tutorialspoint.com/spring_boot/spring_boot_beans_and_dependency_injection.htm 在Spring Boot 中,咱们能够利用 Spring Framework 定义 bean 及其依赖注入。@ComponentScan 及其对应的@Autowired 注解被用于发现和注入 bean。 如果你遵循典型的 Spring Boot 代码构造,那么就不须要应用 @ComponentScan 注解的任何参数。所有的组件类文件都被注册为 Spring Beans。 上面的示例阐明如何主动注入 Rest Template 对象并创立一个雷同的: @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } 以下代码展现如何在主Spring Boot 利用类文件中主动注入 Rest Template 对象及其 Bean 对象: package com.tutorialspoint.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class DemoApplication { @Autowired RestTemplate restTemplate; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); ...

August 11, 2020 · 1 min · jiezi

关于springboot:Spring-cloud-微服务组件-mica-205GA-发布添加对sentinelundertow指标收集

Spring cloud 微服务组件 mica 2.0.5-GA 公布,增加对sentinel、undertow指标收集一、mica(云母)mica 由如梦技术外部的 lutool(撸秃) 演变而来。lutool 诞生于 2017 年,受 jhipster 启发逐步形成一个微服务的外围集。因 lutool 名称与性能不太合乎,故在2019年开源时将其改名为 mica(云母),寓意为云服务的基石。 二、mica 2.x外围依赖mica 基于 java 8,没有历史包袱,反对传统 Servlet 和 Reactive(webflux)。采纳 mica-auto 主动生成 spring.factories 和 spring-devtools.properties 配置,仅依赖 Spring boot、Spring cloud 全家桶,无第三方依赖。市面上鲜有的微服务外围组件。 依赖版本Spring Boot2.3.x三、mica 2.0.5-GA 更新阐明✨ 增加 mica-metrics 模块,用于应用 prometheus 进行指标收集,已反对 undertow、sentinel。✨ mica-redis add scan 和 sscan。???? mica-redis 修复应用文档。 Gitee pr by @醉酒的蝴蝶zzz/N/A✨ mica-core 增加 RsaHelper RSA PEM格局秘钥对的解析和导出,Gitee pr by @caiqiyuan✨ mica-core RsaUtil 欠缺加解密办法。✨ mica-core 增加疏忽序列化 id 的 jdk 对象序列化。✨ mica-core 增加 CheckedPredicate。✨ mica-core 增加 json 格局校验。???? 修复局部 sonarcloud 问题。⬆️ 降级 spring cloud 到 Hoxton.SR7。四、新增 mica-metrics 组件sentinel 指标收集。undertow 指标收集。联合 micrometer-registry-prometheus 组件能够将这些指标数据进行收集。而后展现到 Grafana 中。 ...

August 11, 2020 · 1 min · jiezi

关于springboot:SpringBoot使用devtools导致的类型转换异常

在应用类型转换工具:org.springframework.cglib.beans.BeanCopier时候发现进行VO和DO转换时候总是报错如下: 剖析起因是:SpringBoot应用devtools导致的类型转换异样 参考如下:https://zhuanlan.zhihu.com/p/35949765

August 11, 2020 · 1 min · jiezi

关于springboot:Springboot-系列六web-开发之拦截器和三大组件

文章曾经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所须要把握的外围常识,欢送Star和指教。 欢送关注我的公众号,文章每周更新。1. 拦截器Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置局部。并没有实质的不同,都是通过实现 HandlerInterceptor 中几个办法实现。几个办法的作用一一如下。 preHandle进入 Habdler 办法之前执行,个别用于身份认证受权等。postHandle进入 Handler 办法之后返回 modelAndView 之前执行,个别用于塞入公共模型数据等。afterCompletion最初解决,个别用于日志收集,对立后续解决等。<!-- more --> 1.1 引入依赖 <!-- Spring Boot web 开发整合 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-json</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 阿里 fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- Lombok 工具 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 导入配置文件处理器,在配置springboot相干文件时候会有提醒 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!-- 单元测试 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency>1.2 编写拦截器package net.codingme.boot.config;import lombok.extern.slf4j.Slf4j;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * <p> * 拦截器 * * @Author niujinpeng * @Date 2019/1/6 16:54 */@Slf4jpublic class LogHandlerInterceptor implements HandlerInterceptor { /** * 申请办法执行之前 * 返回true则通过 * * @param request * @param response * @param handler * @return */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { StringBuffer requestURL = request.getRequestURL(); log.info("preHandle申请URL:" + requestURL.toString()); return true; } /** * 返回modelAndView之前执行 * @param request * @param response * @param handler * @param modelAndView */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { log.info("postHandle返回modelAndView之前"); } /** * 执行Handler实现执行此办法 * @param request * @param response * @param handler * @param ex */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { log.info("afterCompletion执行完申请办法齐全返回之后"); }}1.3 配置拦截器省去了 XML 中的拦截器配置局部后,应用 springboot 举荐的形式配置自定义拦截器。 ...

August 11, 2020 · 5 min · jiezi

关于springboot:SpringBoot使用OpenCV总结

前言最近有个我的项目须要对图片图像进行解决,应用到了开源框架OpenCV全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库;而当初的我的项目都是基于SpringBoot,须要把OpenCv整合进去,上面把在应用中遇到的问题进行一个汇总整顿。 下载安装Opencv官网提供了一个多个平台的版本包含:Windows,IOS,Android,地址如下:https://opencv.org/releases/;因为开发在Windows平台,公布在Linux平台,所以咱们这里至多须要两个版本; windows平台间接能够在官网下载opencv-3.4.10-vc14_vc15.exe装置即可,装置完会呈现opencv文件夹在buildjava目录下有咱们须要的opencv-3410.jar,x64/opencv_java3410.dll,x86/opencv_java3410.dll文件; Linux平台Linux平台须要咱们手动编译,下载opencv-3.4.10.zip,解压到/user/local目录下,而后编译装置,执行如下命令: cd /usr/local/opencv-3.4.10mkdir buildcd buildcmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..make -j8sudo make install装置完之后能够在build/bin目录下找到opencv-3410.jar,在build/lib目录下找到libopencv_java3410.so 整合应用两个平台别离装置完之后,获取了对应的dll和so文件;两个平台获取到的jar都是一样的,轻易用哪个都能够,上面看看如何应用 内部援用形式通过把利用jar与本地库文件进行分隔开,而后在我的项目中进行援用 相对路径形式能够通过System.loadLibrary来指定本地库文件,然而这种形式须要在运行时指定-Djava.library.path,具体能够提供配置类: @Configurationpublic class NativeConfig { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }}运行时须要在VM arguments中增加-Djava.library.path=对应dll寄存的门路,不然会呈现如下谬误: Caused by: java.lang.UnsatisfiedLinkError: no opencv_java3410 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860) ~[na:1.8.0_251] at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[na:1.8.0_251] at java.lang.System.loadLibrary(System.java:1122) ~[na:1.8.0_251] at com.springboot.opencv.NativeConfig.<clinit>(NativeConfig.java:10) ~[classes/:na]绝对路径形式能够通过System.load来指定本地库函数的绝对路径: @Configurationpublic class NativeConfig { static { System.load("C:\\Users\\opencv\\build\\java\\x64\\opencv_java3410.dll"); }}踩坑1在IDE中运行应用Opencv性能的时候,呈现如下谬误: java.lang.UnsatisfiedLinkError: org.opencv.imgcodecs.Imgcodecs.imread_1(Ljava/lang/String;)J at org.opencv.imgcodecs.Imgcodecs.imread_1(Native Method) ~[opencv-3.4.10.jar:unknown] at org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:332) ~[opencv-3.4.10.jar:unknown] at com.springboot.opencv.OpenCVController.testOpenCV(OpenCVController.java:13) ~[classes/:na]很显著是在应用jar包外面的办法时没有找到对应的本地库函数,也就是说loadLibrary没有胜利,然而之前其实在本地Java我的项目中是有进行测试的,能够通过的,猜想是不是应用了什么工具导致加载失败,最终锁定在spring-boot-devtools工具包,提供了动静加载等性能,间接移除此工具包,或者配置如下开关: ...

August 9, 2020 · 1 min · jiezi

关于springboot:springboot开发笔记11WebMVC之01静态资源引入

上一节:pringboot开发笔记-(10)-日志框架SLF4J和logback等 11.1 动态资源引入源码解析动态资源引入, springboot webmvc 在 WebMvcAutoConfiguration源码中有两种形式: webjars引入动态资源: 映射形式: /webjars/** ======> classpath:/META-INF/resources/webjars/** 指定的几个目录 映射形式: "/**" ======> classpath: [/META-INF/resources/, /resources/, /static/, /public/] META-INF/resources//resources//static//public/详见: WebMvcAutoConfiguration源码的解析: @Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); // #1. "webjars"目录映射=> classpath:/META-INF/resources/webjars/ if (!registry.hasMappingForPattern("/webjars/**")) { customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") // 对应下面的 jquery.js目录: .addResourceLocations("classpath:/META-INF/resources/webjars/") .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); } // #2."/**"目录映射 => classpath:[/META-INF/resources/, /resources/, /static/, /public/] String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); }}// 下面23行的: this.resourceProperties.getStaticLocations(): ...

August 7, 2020 · 1 min · jiezi

关于springboot:springboot开发笔记11WebMVC之01静态资源引入

上一节:pringboot开发笔记-(10)-日志框架SLF4J和logback等 11.1 动态资源引入源码解析动态资源引入, springboot webmvc 在 WebMvcAutoConfiguration源码中有两种形式: webjars引入动态资源: 映射形式: /webjars/** ======> classpath:/META-INF/resources/webjars/** 指定的几个目录 映射形式: "/**" ======> classpath: [/META-INF/resources/, /resources/, /static/, /public/] META-INF/resources//resources//static//public/详见: WebMvcAutoConfiguration源码的解析: @Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); // #1. "webjars"目录映射=> classpath:/META-INF/resources/webjars/ if (!registry.hasMappingForPattern("/webjars/**")) { customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") // 对应下面的 jquery.js目录: .addResourceLocations("classpath:/META-INF/resources/webjars/") .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); } // #2."/**"目录映射 => classpath:[/META-INF/resources/, /resources/, /static/, /public/] String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); }}// 下面23行的: this.resourceProperties.getStaticLocations(): ...

August 7, 2020 · 1 min · jiezi

关于springboot:springboot开发笔记9自动装配与EnableAutoConfiguration和Conditinal

上一节:springboot开发笔记-(8)-配置文件的加载程序 springboot主动拆卸原理和两个注解类的关系是深有千千结: @EnableAutoConfiguration和@Conditinal 咱们从springboot的启动类上的注解看下这千头万绪: 张宇的《一言难尽》不是有这么几句: 从哪里开始 从哪里失去我一言难尽 忍不住伤心掂量不出爱或不爱之间的间隔模摸糊糊中 明确你的决定不敢勉强你 只好尴尬本人我尴尬我本人...9.1 从哪里开始: @SpringBootApplicationpackage com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); }}@SpringBootApplication: @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration // 1@EnableAutoConfiguration // 2@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {}咱们来说下这两个注解的性能 : // 1. 次要是讲此类标识为: @Configuration, 作为配置类, 让spring容器启动辨认; // 2. @EnableAutoConfiguration次要是主动拆卸; 上面细说 它; 9.2 主动拆卸去: @EnableAutoConfiguration:@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage // 3@Import(AutoConfigurationImportSelector.class) // 4public @interface EnableAutoConfiguration @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import(AutoConfigurationPackages.Registrar.class) // 5public @interface AutoConfigurationPackage {}// 3. @AutoConfigurationPackage 次要做了什么? 看注解链: ...

August 6, 2020 · 5 min · jiezi

关于springboot:修炼内功springboot-1-SpringBoot是如何实现自动装配的

本文已收录【修炼内功】跃迁之路 微信关注“林中小舍”,林小二带你聊技术!上篇文章 Spring Framework中的注解是如何运作的 介绍了Spring Framework中各种注解的运作形式,(在SpringBoot推出之前)对于组件的应用还须要手动进行配置(无论xml/groovy文件形式还是注解形式),如DataSource、SessionFactory、TransactionManager、DispatcherServlet等等 SpringBoot提供了一种新的形式用于简化Spring利用的搭建及开发过程,通过各种starter实现组件的主动拆卸(autoconfig),将约定优于配置体现的酣畅淋漓,在此基础上还提供了泛滥扩大点用以批改约定的配置及默认的组件性能 那,SpringBoot是如何实现主动拆卸的?(SpringBoot提供的starter列表见 Using boot starter) 疾速生成Boot利用 SpringBoot脚手架:https://start.spring.io/PandoraBoot脚手架(阿里外部):http://mw.alibaba-inc.com/boo...SpringBoot的启动SpringBoot利用个别会将 SpringApplication 及 @SpringBootApplication 放一起配合应用 @SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.setWebApplicationType(WebApplicationType.NONE); app.run(args); // 或者 // SpringApplication.run(Application.class, args); // 或者 // new SpringApplicationBuilder(Application.class) // .profiles("dev") // .properties("spring.application.name=spring-boot-demo") // .run(args); }}这里,不肯定非要应用@SpringBootApplication注解,SpringApplication也不肯定非要放在main入口中在此,将SpringApplication及@SpringBootApplication的作用分两个小结详解 上例中展现了三种SpringApplication的编码方式,但不管何种形式都离不开两个步骤:创立(SpringApplication#new);运行(SpringApplication#run) SpringApplication创立在SpringApplication创立过程中初始化了一些参数,各参数的作用/应用会在下文中得以解释 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { // ResourceLoader this.resourceLoader = resourceLoader; // 主入口类 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // web类型 NONE | SERVLET | REACTIVE this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 设置initializers(org.springframework.context.ApplicationContextInitializer) setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 设置listeners(org.springframework.context.ApplicationListener) setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // main函数所处的类 this.mainApplicationClass = deduceMainApplicationClass();}这里须要着重介绍的是在初始化某些参数时应用的一些逻辑 ...

August 6, 2020 · 3 min · jiezi

关于springboot:springboot开发笔记8配置文件的加载顺序

上一节:springboot开发笔记-(7)-Profile多环境配置文件加载 8.1 配置文件的优先级server.servlet.context-path=/appserver.port=8888spring.config.location=xxx/xxx/application.properties上面本文中说到"级别高"意思就是会替换其余的, 以它为首选, 它最终会起作用, 其余的会被笼罩; 本节要答复的问题:springboot利用部署后, 配置文件以哪个为准? 如果利用打包成可执行app.jar后有以下这几个配置文件: jar同目录的 _application.properties_; ->官网称此为: file:./config/jar同目录的 _config/application.properties_; ->官网称此为: file:./config/jar外部jar包中的 _classes/application.properties_; ->官网称此为: classpath:/jar外部jar包中的 _classes/config/application.properties_; ->官网称此为: classpath:/config/启动参数时间接笼罩某个单项配置, 比方改端口号: java -jar app.jar --server.port=9999来指定;轻易指定一个地址搁置 application.properties , 应用 启动参数spring.config.location=xxx来指定; (留神: 这个配置实测会互补生效--即: 只有它本人起作用)--let's guess: 咱们先来做一个猜想, 如果是让咱们本人设计, 设想实际上线的场景, 咱们会冀望哪个优先级最高(最终会笼罩其余配置的)? 如果我在线上部署了一个app.jar文件, 执行java -jar app.jar 启动利用; 启动之后线上如果有问题了, 比方端口被占用, 比方数据库配置批改, 我须要马上调整一个参数, 最快的形式是什么? 首先: 间接重启, java -jar app.jar --some.prop=new_value 必定是这个最快, 或者罗唆本人指定一个配置文件的地址, --参数加命令行前面; (下面5/6)除了执行带参数, 不便批改的必定是 jar平级目录下了, 那么, 应该轮到 app.jar平级目录下的配置了:是设置哪个级别高呢? 间接读取application.properties? 还是 config/application.properties? ...

August 6, 2020 · 7 min · jiezi

关于springboot:springboot开发笔记7Profile多环境配置文件加载

上一节: springboot开发笔记-(6)-属性占位符以及默认值7.1 properties配置文件:多个文件多环境3个配置文件: application.properties application-dev.properties application-prod.properties 第1个: application.properties server.port=8888spring.profiles.active=devperson.firstName=新名person.lastName=${random.uuid}person.age=${random.int(100)}person.male=trueperson.birth=1985/03/03person.maps.k1=v1person.maps.k2=20person.maps.k3=trueperson.lists=lisi,wangwuperson.dog.name=${person.firstName:无名}_小dperson.dog.age=${random.int[30,40]}第2个: application-dev.properties server.port=9999person.lastName=${random.uuid}person.age=${random.int(100)}person.male=trueperson.birth=1985/03/03person.maps.k1=v1person.maps.k2=20person.maps.k3=trueperson.lists=lisi,wangwuperson.dog.name=${person.firstName:无名dev}_小dev#person.dog.age=${random.int[10,20]}第3个: application-prod.properties server.port=7777person.lastName=${random.uuid}person.age=${random.int(100)}person.male=trueperson.birth=1985/03/03person.maps.k1=v1person.maps.k2=20person.maps.k3=trueperson.lists=lisi,wangwuperson.dog.name=${person.firstName:无名prod}_小prodperson.dog.age=${random.int[20,30]}利用启动的时候, 先去 第1个 配置文件 application.properties中找 spring.profiles.active=dev 找到 dev 这样, 就会读取application-dev.properties 的配置文件来加载; 那么问题来了: 7.2.1 配置文件加载程序是怎么?先加载 application.properties中的配置而后加载application-dev.properties中的配置, 如果反复的, 用dev去笼罩下面的; 如果dev中没有的, application.properties中的配置就失效!7.2.2 dev是active的话, application.properties中其余配置还会加载吗?答复如上: 会失效, 除非dev中的笼罩了;下面三个配置文件设置后, person对象的属性加载后果是: 可见 person.dog.age被application.properties的起作用了; {"lastName":"94b68ef1-33d2-4866-9b62-32c5fb983f22","age":47,"male":true,"birth":"Mar 3, 1985 12:00:00 AM","maps":{"k1":"v1","k2":"20","k3":"true"},"lists":["lisi","wangwu"],"dog":{"name":"新名_小dev","age":32}}7.2 yml配置文件: 一个文件多环境spring: profiles: active: prodperson: firstName: newName---spring: profiles: devserver: port: 5555person: lastName: ${random.uuid} # uuid age: ${random.int(100)} # 0-100的随机值 male: true birth: 1985/03/03 maps: {k1: v1, k2: 20, k3: true} lists: - lisi - wangwu dog: name: ${person.firstName:无名}_小黄dev #如果为空, 取默认值 age: ${random.int[1,3]} #10-20之间的随机值: 两头还不能有空格, 实测!---spring: profiles: prodserver: port: 6666person: lastName: ${random.uuid} # uuid age: ${random.int(100)} # 0-100的随机值 male: true birth: 1985/03/03 maps: {k1: v1, k2: 20, k3: true} lists: - lisi - wangwu dog: name: ${person.firstName:无名}_小黄prod #如果为空, 取默认值 age: ${random.int[4,6]} #10-20之间的随机值: 两头还不能有空格, 实测!---能够作为文档宰割符号 ...

August 5, 2020 · 1 min · jiezi

关于springboot:springboot开发笔记6属性占位符以及默认值

上一节:SpringBoot开发笔记-(5)-导入内部资源: @ImportResource 6.1 随机数${random.value} ${random.int} ${random.long} ${random.uuid} : 随机uuid字符串; ${random.int(10)} : 从0-10中的一个随机数; ${random.int[10,20]} : 从10到20两头的一个随机数, 注: 通过测试, 10和20两头还不能有空格, 否则有效! 6.2 如果没有,指定默认值:${person.lastName:无名} person: lastName: ${random.uuid} age: ${random.int(100)} male: true birth: 1985/03/03 maps: {k1: v1, k2: 20, k3: true} lists: - lisi - wangwu dog: name: ${person.lastName:无名}_小黄 age: ${random.int[10,20]}{"lastName":"dffc65aa-8d1b-4110-ada5-debcf59d199b","age":98,"male":true,"birth":"Mar 3, 1985 12:00:00 AM","maps":{"k1":"v1","k2":20,"k3":true},"lists":["lisi","wangwu"],"dog":{"name":"34c4bf97-2885-4a61-b0e6-f9fb176fc86f_小黄","age":11}}如果把lastName->firstName, 找不到此字段, 就会应用默认值: "无名" dog: name: ${person.firstName:无名}_小黄{"lastName":"6ea9265a-a0a2-45cf-bdde-95fbd71305cf","age":39,"male":true,"birth":"Mar 3, 1985 12:00:00 AM","maps":{"k1":"v1","k2":20,"k3":true},"lists":["lisi","wangwu"],"dog":{"name":"无名_小黄","age":17}}

August 5, 2020 · 1 min · jiezi

关于springboot:SpringBoot开发笔记5导入外部资源-ImportResource

上一节:SpringBoot开发笔记-(4) 属性文件读取2: @PropertySource 5.1 前情提要-场景之前的2节都是讲怎么读取配置文件; 然而如果有下列的状况, 就须要用到@ImportResource来帮忙了: 有一个遗留的xml文件, 比方名叫 spring-beans.xml 外面有很多的配置bean, 都须要注册到spring容器中, 让容器来治理这些bean以备不时之需;传统springmvc的我的项目, 原来的xml配置文件不想删除, 然而又想用springboot来革新它; 就能够应用 @ImportResource来 导入内部资源简言之: 就是还想用xml, 还想用 springboot; xml就由此注解来注册进去! 5.2. 示例启动类上加注解: @ImportResource("classpath:/spring/spring-*.xml")package com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@SpringBootApplication@ImportResource("classpath:/spring/spring-*.xml")public class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); }}resource: spring/spring-html.xml文件:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= --> <!-- RestTemplate --> <bean id="httpClient" class="com.niewj.springboot.utils.MyHttpClientUtils" factory-method="buildHttpClient"/> <bean id="clientHttpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> <property name="connectTimeout" value="20000"/><!-- 连贯超时 --> <property name="readTimeout" value="30000"/><!-- 数据读取超时工夫 --> <property name="connectionRequestTimeout" value="20000"/> <!-- 连贯不够用的等待时间 --> <constructor-arg ref="httpClient"/> </bean> <bean id="restTemplate" class=" org.springframework.web.client.RestTemplate"> <constructor-arg ref="clientHttpRequestFactory"/> </bean></beans>这个xml中心愿失去一个 RestTemplate的bean, 须要依赖一个httpClient, httpClient代码咱们本人写的, 如下: ...

August 5, 2020 · 2 min · jiezi

关于springboot:SpringBoot开发笔记4-属性文件读取2-PropertySource

上一节:SpringBoot开发笔记-(3) 属性文件读取1: @ConfigurationProperties读取yml配置文件 上一节用到了@ConfigurationProperties会加载配置文件application.yml或application.properties配置中的属性; 然而如果咱们须要本人独自定义的属性文件的时候, 就要用到 本人指定属性源了: @PropertySource 4.1 应用示例maven: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>com.niewj</groupId> <artifactId>springboot-01-helloworld</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-01-helloworld</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- @RunWith都是来自它 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>Person.java: ...

August 5, 2020 · 1 min · jiezi

关于springboot:SpringBoot开发笔记4-属性文件读取2-PropertySource

上一节:SpringBoot开发笔记-(3) 属性文件读取1: @ConfigurationProperties读取yml配置文件 上一节用到了@ConfigurationProperties会加载配置文件application.yml或application.properties配置中的属性; 然而如果咱们须要本人独自定义的属性文件的时候, 就要用到 本人指定属性源了: @PropertySource 4.1 应用示例maven: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>com.niewj</groupId> <artifactId>springboot-01-helloworld</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-01-helloworld</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- @RunWith都是来自它 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>Person.java: ...

August 5, 2020 · 1 min · jiezi

关于springboot:SpringBoot开发笔记3-属性文件读取1-ConfigurationProperties读取yml配置文件

3.1 ConfigurationProperties应用形式3.1.1. 步骤@Component+@ConfigurationProperties(prefix="person") person是在yml中配置的前缀: person: ... 3.1.2. 样例(1). maven依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.niewj</groupId> <artifactId>springboot-study</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring-boot-version>2.3.2.RELEASE</spring-boot-version> </properties> <modules> <module>springboot-01-helloworld</module> </modules> <!-- 示意是一个pom总的父工程 --> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot-version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- springboot测试用例须要的依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- ConfigurationProperties属性配置工具依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- json依赖 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> <build> <plugins> <!-- 解决 ConfigurationProperties报错 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build></project>(2). 样例之:person.java ...

August 5, 2020 · 2 min · jiezi

关于springboot:SpringBoot开发笔记3-属性文件读取1-ConfigurationProperties读取yml配置文件

3.1 ConfigurationProperties应用形式3.1.1. 步骤@Component+@ConfigurationProperties(prefix="person") person是在yml中配置的前缀: person: ... 3.1.2. 样例(1). maven依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.niewj</groupId> <artifactId>springboot-study</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring-boot-version>2.3.2.RELEASE</spring-boot-version> </properties> <modules> <module>springboot-01-helloworld</module> </modules> <!-- 示意是一个pom总的父工程 --> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot-version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- springboot测试用例须要的依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- ConfigurationProperties属性配置工具依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>${spring-boot-version}</version> </dependency> <!-- json依赖 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> <build> <plugins> <!-- 解决 ConfigurationProperties报错 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build></project>(2). 样例之:person.java ...

August 5, 2020 · 2 min · jiezi

关于springboot:Spring-Boot快速入门之四Tomcat-部署

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_tomcat_deployment.htm 应用 Spring Boot 利用,咱们能够创立一个 war 文件部署到 web 服务器中。本文解说如何创立 war 文件并将 Spring Boot 利用部署到 Tomcat web 服务器中。 Spring Boot Servlet 初始化器传统的部署形式是将 Spring Boot 利用中 @SpringBootApplication 注解的类扩大自 SpringBootServletInitializer 类。Spring Boot Servlet Initializer 类文件容许你在应用 Servlet 窗口启动时配置利用。 用于 JAR 文件部署的 Spring Boot 利用类文件示例如下: package com.tutorialspoint.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } 咱们须要扩大类 SpringBootServletInitializer 以反对 WAR 文件部署。对应的 Spring Boot 利用类文件如下: ...

August 5, 2020 · 3 min · jiezi

关于springboot:SpringBoot开发笔记2-springboot原理初探解析helloworld

2.1 父依赖: starter-parenthelloworld查看依赖: 我的项目依赖了 spring-boot-stater-parent: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId></dependency>spring-boot-stater-parent点进去, 外面还依赖了个parent: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.2.RELEASE</version></parent>spring-boot-dependencies再点进去: 一大堆 properties 一大堆 dependencies 可见: spring-boot-dependencies 才是springboot 所有依赖真正管理者;2.2 导入的依赖: starter-web<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>点进去: spring-boot-starter-web帮咱们导入了web我的项目所依赖的依赖项: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency></dependencies>spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvcstarter: spring boot帮忙治理依赖资源; spring提供了一系列starter: mail/web/jpa/mq... 2.3 @SpringBootApplication注解注解类: //....SpringBootApplication...@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration // 1@EnableAutoConfiguration // 2@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {..... //....SpringBootConfiguration...@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configuration // 3public @interface SpringBootConfiguration { ..... //....Configuration...@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Component // 4public @interface Configuration {次要注解类: ...

August 4, 2020 · 2 min · jiezi

关于springboot:SpringBoot开发笔记2-springboot原理初探解析helloworld

2.1 父依赖: starter-parenthelloworld查看依赖: 我的项目依赖了 spring-boot-stater-parent: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId></dependency>spring-boot-stater-parent点进去, 外面还依赖了个parent: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.2.RELEASE</version></parent>spring-boot-dependencies再点进去: 一大堆 properties 一大堆 dependencies 可见: spring-boot-dependencies 才是springboot 所有依赖真正管理者;2.2 导入的依赖: starter-web<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>点进去: spring-boot-starter-web帮咱们导入了web我的项目所依赖的依赖项: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency></dependencies>spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvcstarter: spring boot帮忙治理依赖资源; spring提供了一系列starter: mail/web/jpa/mq... 2.3 @SpringBootApplication注解注解类: //....SpringBootApplication...@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration // 1@EnableAutoConfiguration // 2@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {..... //....SpringBootConfiguration...@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configuration // 3public @interface SpringBootConfiguration { ..... //....Configuration...@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Component // 4public @interface Configuration {次要注解类: ...

August 4, 2020 · 2 min · jiezi

关于springboot:SpringBoot开发笔记1-springboot简介和helloworld

1.1 长处:简化spring开发/约定优于配置 : 嵌入式的servlet容器;starter主动依赖和版本控制;大量主动配置, 简化开发;无需配置xml, 无代码生成, 开箱即用;利用监控:准生产环境的运行时利用监控;1.2 毛病:入门容易, 精通难~ 1.3 微服务springboot: 一个利用, 是一组小型服务, 能够通过http形式进行互通; 每一个性能元素都是一个能够独立替换和独立降级的单元; springcloud: 整个利用的大型分布式网格之间的调用; 1.4 helloworld1.4.1 maven依赖:<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.niewj</groupId> <artifactId>springboot-study</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring-boot-version>2.3.2.RELEASE</spring-boot-version> </properties> <modules> <module>springboot-01-helloworld</module> </modules> <!-- 示意是一个pom总的父工程 --> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot-version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-version}</version> </dependency> </dependencies></project>1.4.2 类文件:SpringBootApplication 启动类 package com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * Created by niewj on 2020/8/4 18:04 */@SpringBootApplicationpublic class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); }}HelloController.java ...

August 4, 2020 · 1 min · jiezi

关于springboot:SpringBoot开发笔记1-springboot简介和helloworld

1.1 长处:简化spring开发/约定优于配置 : 嵌入式的servlet容器;starter主动依赖和版本控制;大量主动配置, 简化开发;无需配置xml, 无代码生成, 开箱即用;利用监控:准生产环境的运行时利用监控;1.2 毛病:入门容易, 精通难~ 1.3 微服务springboot: 一个利用, 是一组小型服务, 能够通过http形式进行互通; 每一个性能元素都是一个能够独立替换和独立降级的单元; springcloud: 整个利用的大型分布式网格之间的调用; 1.4 helloworld1.4.1 maven依赖:<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.niewj</groupId> <artifactId>springboot-study</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring-boot-version>2.3.2.RELEASE</spring-boot-version> </properties> <modules> <module>springboot-01-helloworld</module> </modules> <!-- 示意是一个pom总的父工程 --> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot-version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-version}</version> </dependency> </dependencies></project>1.4.2 类文件:SpringBootApplication 启动类 package com.niewj.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * Created by niewj on 2020/8/4 18:04 */@SpringBootApplicationpublic class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); }}HelloController.java ...

August 4, 2020 · 1 min · jiezi

关于springboot:Thymeleaf常用标签说明

之前在咱们开发我的项目,做view试图模块时,咱们通常是应用JSP,然而随着技术的倒退,以及springboot的应用日渐增多,在springboot的我的项目中曾经慢慢不再应用JSP去作为view,而是逐步采纳了Thymeleaf这项技术. Thymeleaf简略地说,Thymeleaf是一个html模板引擎,提供了与Spring MVC进行整合的API,可作为MVC架构中Web利用的View层. 而在springboot中导入Thymeleaf的办法也在上文--thymeleaf导入中有所介绍,也不做过多赘述. 然而有一点须要留神:可能在开发过程中,大家会感觉每次更改页面后,都要从新重启服务,很是麻烦与反人类,能够通过配置热启动来改善. spring.thymeleaf.cache=falsecache是thymeleaf带有的一个缓存区,咱们将它设置为false即可不须要每次重启服务,间接刷新界面就能够(但要留神服务端的代码批改的话还是须要重启服务器) 但也不要一味的认为cache的设置就是麻烦的,它次要的作用是要在我的项目上线时设置为true(不设置默认为true),这样它会提供一个缓存区,不必每次都向服务器申请数据,能够无效的进步响应速度. Thymeleaf标签关与Thymeleaf标签的具体应用在官网中的文档中都能够找到,本文只是说一些罕用到的标签,详解还请参照官网文档. 数据迭代在thymeleaf中数据的循环迭代应用的是th:each="x1:${x2}",作用能够取出域中的数据(数组/汇合)去进行循环,通常配合th:text="${x1.x3}"应用. 其中x2为域中存储的数据名称;x1为本人定义的名称,用于在页面中应用数据;x3为x2中的属性,要和get办法名统一. 代码如下: <tr th:each="g:${list}"> <td th:text="${g.id}"></td> <td th:text="${g.name}"></td></tr>超链接在thymeleaf中超链接应用th:href="@{x1(x2=${x3.x4})}", x1为超链接指向的门路;x2为本人命名的名称;x3,x4为上边数据迭代中的th:text="${x1.x3}"x1和x3. 代码如下: <a th:href="@{/goods/doDeleteById(id=${g.id})}">delete</a>对于超链接指向地址,还提供了restful格调的写法,平时咱们所写代码地址上带申请数据个别为:a/b/c?id=x而restful这种格调为:a/b/c/{id} 代码如下: <a th:href="@{/goods/doFindById/{id}(id=${g.id})}">update</a>在这种语法中,{id}为一个变量表达式,由前面()内的内容补充,如果咱们心愿在后端的Controller类的办法参数中取得传递的参数,就须要加@PathVariable形容参数. 提交表单在thymeleaf中提交表单采纳th:action="@{x1}" x1为表单所要提交至的地址. 代码如下: <form th:action="@{/goods/doUpdateGoods}" method="POST"><input type="text" name="name" th:value="${goods.name}">当你感觉上述代码如果显示时有很多属性,而每个属性都须要${对象名.属性名}的形式来显示会很反复,想把对象名间接提取进去,能够通过在表单上加th:object, 代码如下: <form th:action="@{/goods/doUpdateGoods}" method="POST" th:object="${goods}"><input type="text" name="name" th:value="${name}">拓展1)当咱们的url地址没有以"/"结尾时,默认这个内容要替换到当初地址栏url最初一个"/"后的内容进行拼接. 2)申请转发:return "forward:doGoodsUI";重定向:return "redirect:/goods/doGoodsUI";申请转发因为是服务端外部转发所以能够不写"/",间接跳转;而重定向因为是二次申请二次响应,且能够跳转至别的资源甚至是别的服务器,所以须要写相对地址,必须以"/"结尾!

August 4, 2020 · 1 min · jiezi

关于springboot:Thymeleaf常用标签说明

之前在咱们开发我的项目,做view试图模块时,咱们通常是应用JSP,然而随着技术的倒退,以及springboot的应用日渐增多,在springboot的我的项目中曾经慢慢不再应用JSP去作为view,而是逐步采纳了Thymeleaf这项技术. Thymeleaf简略地说,Thymeleaf是一个html模板引擎,提供了与Spring MVC进行整合的API,可作为MVC架构中Web利用的View层. 而在springboot中导入Thymeleaf的办法也在上文--thymeleaf导入中有所介绍,也不做过多赘述. 然而有一点须要留神:可能在开发过程中,大家会感觉每次更改页面后,都要从新重启服务,很是麻烦与反人类,能够通过配置热启动来改善. spring.thymeleaf.cache=falsecache是thymeleaf带有的一个缓存区,咱们将它设置为false即可不须要每次重启服务,间接刷新界面就能够(但要留神服务端的代码批改的话还是须要重启服务器) 但也不要一味的认为cache的设置就是麻烦的,它次要的作用是要在我的项目上线时设置为true(不设置默认为true),这样它会提供一个缓存区,不必每次都向服务器申请数据,能够无效的进步响应速度. Thymeleaf标签关与Thymeleaf标签的具体应用在官网中的文档中都能够找到,本文只是说一些罕用到的标签,详解还请参照官网文档. 数据迭代在thymeleaf中数据的循环迭代应用的是th:each="x1:${x2}",作用能够取出域中的数据(数组/汇合)去进行循环,通常配合th:text="${x1.x3}"应用. 其中x2为域中存储的数据名称;x1为本人定义的名称,用于在页面中应用数据;x3为x2中的属性,要和get办法名统一. 代码如下: <tr th:each="g:${list}"> <td th:text="${g.id}"></td> <td th:text="${g.name}"></td></tr>超链接在thymeleaf中超链接应用th:href="@{x1(x2=${x3.x4})}", x1为超链接指向的门路;x2为本人命名的名称;x3,x4为上边数据迭代中的th:text="${x1.x3}"x1和x3. 代码如下: <a th:href="@{/goods/doDeleteById(id=${g.id})}">delete</a>对于超链接指向地址,还提供了restful格调的写法,平时咱们所写代码地址上带申请数据个别为:a/b/c?id=x而restful这种格调为:a/b/c/{id} 代码如下: <a th:href="@{/goods/doFindById/{id}(id=${g.id})}">update</a>在这种语法中,{id}为一个变量表达式,由前面()内的内容补充,如果咱们心愿在后端的Controller类的办法参数中取得传递的参数,就须要加@PathVariable形容参数. 提交表单在thymeleaf中提交表单采纳th:action="@{x1}" x1为表单所要提交至的地址. 代码如下: <form th:action="@{/goods/doUpdateGoods}" method="POST"><input type="text" name="name" th:value="${goods.name}">当你感觉上述代码如果显示时有很多属性,而每个属性都须要${对象名.属性名}的形式来显示会很反复,想把对象名间接提取进去,能够通过在表单上加th:object, 代码如下: <form th:action="@{/goods/doUpdateGoods}" method="POST" th:object="${goods}"><input type="text" name="name" th:value="${name}">拓展1)当咱们的url地址没有以"/"结尾时,默认这个内容要替换到当初地址栏url最初一个"/"后的内容进行拼接. 2)申请转发:return "forward:doGoodsUI";重定向:return "redirect:/goods/doGoodsUI";申请转发因为是服务端外部转发所以能够不写"/",间接跳转;而重定向因为是二次申请二次响应,且能够跳转至别的资源甚至是别的服务器,所以须要写相对地址,必须以"/"结尾!

August 4, 2020 · 1 min · jiezi

关于springboot:基本业务的实现

基于id执行商品信息删除增加mybatis依赖spring框架启动时会对mybatis进行主动配置,帮咱们创立SqlSessionFactory工厂(让咱们能应用@Mapper注解来形容数据长久层)第二步:定义商品业务数据层接口及业务办法 package com.cy.pj.goods.dao;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Mapper;@Mapperpublic interface GoodsDao { @Delete("delete from tb_goods where id=#{id}") int deleteById(Integer id);}其中:@Mapper是由MyBatis框架中定义的一个形容数据接口的注解(所有的注解只是起标识作用),通知Spring框架此接口的实现由MyBatis创立,并将其实现类贮存到Spring容器中第三步:定义测试类,对GoodsDao对象进行利用测试 @SpringBootTestpublic class GoodsDaoTests { @Autowired private GoodsDao goodsDao; @Test public void testDeleteById() { int rows=goodsDao.deleteById(10); System.out.println("rows="+rows); }}调用长久层接口 应用删除办法,打印执行信息,查看是否胜利 业务进阶剖析及实现在MyBais框架中定义Sql映射有两种:1.将SQL映射定义在咱们的xml映射文件中(适宜比较复杂的sql语句,应用时充分利用动静的sql进行设计,如<where>,<if>...这些标签) 2.间接以注解的形式进行申明(简略的sql语句)应用映射文件时,在src/main/resources目录下创立mapper/goods目录,而后在其目录中增加GoodsMapper.xml映射文件,并指定以下内容 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"\><mapper namespace="com.cy.pj.goods.dao.GoodsDao"\> <delete id="deleteObjects"\> delete from tb\_goods where id in <!-- (1,2,3,4,5) --> <foreach collection="ids" open="(" close=")" separator="," item="id"\> #{id} </foreach\> </delete\></mapper\>1)xml文件的文件头是从mybatis官网cv的2)namespace 指向的是长久层类的类全称3)办法的id值要和接口中的办法名保持一致迭代时只能迭代 "ids" "array" 这两种元素collection指向肯定要填写其中之一,并且接口的办法类型要对应上 int deleteObjects(@param("ids")Integer...ids);其中@param("ids") ids要和数组名称对应 Integer...ids是一个名字为ids的一个数组(三个点示意数组~~~~)在启动类中增加下列配置,这个配置指向的就是sql映射文件 mybatis.mapper-locations=classpath:/mapper/*/*.xml在GoodsDaoTests类中增加一个单元测试办法进行测试,查看办法运行是否有误 ...

August 3, 2020 · 1 min · jiezi

关于springboot:个人学习系列-Spring-Boot-ShardingSphere-JPA-实现读写分离

最近想要学习一下分库分表,可是分库分表之前能够先用数据库的读写拆散来过渡一下,当然这还须要主从服务器来配合。明天就先写数据库的读写拆散,当前再介绍主从服务器。。。Mysql1. 新建三个数据库CREATE DATABASE database0;USE database0;DROP TABLE IF EXISTS `user`;CREATE TABLE `user`( id bigint(64) not null auto_increment, city varchar(20) not null, name varchar(20) not null, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE DATABASE database1;USE database1;DROP TABLE IF EXISTS `user`;CREATE TABLE `user`( id bigint(64) not null auto_increment, city varchar(20) not null, name varchar(20) not null, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `database1`.`user`(`id`, `city`, `name`) VALUES (001, '青岛', '测试库1');CREATE DATABASE database2;USE database2;DROP TABLE IF EXISTS `user`;CREATE TABLE `user`( id bigint(64) not null auto_increment, city varchar(20) not null, name varchar(20) not null, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `database2`.`user`(`id`, `city`, `name`) VALUES (002, '胶州', '测试库2');2. 新建springboot我的项目2.1 pom.xml <!-- web依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mybatis依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!-- mysql依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- druid数据库连接池依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.23</version> </dependency> <!-- ShardingSphere依赖 --> <dependency> <groupId>io.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>3.1.0</version> </dependency> <!-- jap依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>2.2 application.ymlserver: # 端口号 port: 8888sharding: jdbc: dataSource: names: db-test0,db-test1,db-test2 # 配置主库 db-test0: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://ip:3306/database0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT username: 账户 password: 明码 #最大连接数 maxPoolSize: 20 db-test1: # 配置第一个从库 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://ip:3306/database1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT username: 账户 password: 明码 maxPoolSize: 20 db-test2: # 配置第二个从库 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://ip:3306/database2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT username: 账户 password: 明码 maxPoolSize: 20 config: masterslave: # 配置读写拆散 load-balance-algorithm-type: round_robin # 配置从库抉择策略,提供轮询与随机,这里抉择用轮询//random 随机 //round_robin 轮询 name: db1s2 master-data-source-name: db-test0 slave-data-source-names: db-test1,db-test2 props: sql: show: true # 开启SQL显示,默认值: false,留神:仅配置读写拆散时不会打印日志!!!spring: main: allow-bean-definition-overriding: true # 容许重名的bean能够被笼罩 jpa: hibernate: ddl-auto: update # 每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新 naming: # 驼峰命名法 physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy show-sql: true # 打印sql2.3 新建User实体类/** * 实体类 * * @author zhouzhaodong */@Entity@Table(name = "user")public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String city; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getName() { return name; } public void setName(String name) { this.name = name; }}2.4 新建 UserRepository/** * 数据拜访层 * * @author zhouzhaodong */@Repositorypublic interface UserRepository extends JpaRepository<User, Long> {}2.5 新建服务层UserService/** * 服务层 * * @author zhouzhaodong */public interface UserService { /** * 新增 * * @param user * @return */ User addUser(User user); /** * 查问所有 * * @return */ List<User> list();}2.6 新建服务层实现类UserServiceImpl/** * 服务层实现类 * * @author zhouzhaodong */@Servicepublic class UserServiceImpl implements UserService { @Resource UserRepository userRepository; @Override public User addUser(User user) { // 强制路由主库// HintManager.getInstance().setMasterRouteOnly(); return userRepository.save(user); } @Override public List<User> list() { return userRepository.findAll(); }}2.7 新建管制层 UserController/** * 管制层 * * @author zhouzhaodong */@RestControllerpublic class UserController { @Resource private UserService userService; @GetMapping("/users") public Object list() { return userService.list(); } @PostMapping("/add") public Object add(String name, String city) { User user = new User(); user.setCity(city); user.setName(name); return userService.addUser(user); }}2.8 启动类不须要任何操作3. 启动我的项目进行测试即可3.1 第一次拜访 localhost:8888/users ...

August 3, 2020 · 3 min · jiezi

关于springboot:spring51x源码学习整体思维导图

Spring5 源码剖析思维导图为了更好的浏览剖析spring5.1.x的源码,须要对须要钻研的模块有个大略的理解,从启动流程开始再具体debug各个模块的细节,从而学习其中的精华 Spring5 零碎架构 Spirng 各模块之间的依赖关系该图是 Spring5 的包构造, 能够从中分明看出 Spring 各个模块之间的依赖关系 Spirng 罕用jar包 Spirng 源码剖析导图

August 2, 2020 · 1 min · jiezi

关于springboot:spring51x源码学习整体思维导图

Spring5 源码剖析思维导图为了更好的浏览剖析spring5.1.x的源码,须要对须要钻研的模块有个大略的理解,从启动流程开始再具体debug各个模块的细节,从而学习其中的精华 Spring5 零碎架构 Spirng 各模块之间的依赖关系该图是 Spring5 的包构造, 能够从中分明看出 Spring 各个模块之间的依赖关系 Spirng 罕用jar包 Spirng 源码剖析导图

August 2, 2020 · 1 min · jiezi

关于springboot:Failed-to-parse-multipart-servlet-request

Failed to parse multipart servlet request; nested exception is java.io.IOException springboot线上的我的项目呈现此情况Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.6132688910850781933.8089/work/Tomcat/localhost/ROOT] is not valid 起因应用http post申请时,须要应用长期目录存放数据以后的临时文件门路是被长期创立的,但因为centos的零碎机制,temp目录会定时回收和删除的,因而运行了些时日后的我的项目,就会遇见此情况,没找到对应的目录解决1. 重启我的项目对于一些demo示例性的,学习性,试验测试性的我的项目,能够间接重新启动我的项目则能够解决。同样,也能够针对报错提醒的门路,进行建设相干的门路。 然而,对于已在线上的生产环境的我的项目,上述办法都不太倡议。 2. 批改springboot的配置在application配置文件中的server-tomcat减少一项配置basedir: /data/temp,使得临时文件寄存在指定的目录下,不会被零碎回收删除。 批改实现后,重新部署我的项目。 server: tomcat: basedir: /data/temp

August 2, 2020 · 1 min · jiezi

关于springboot:SpringBoot整合Mybatis框架

应用工具SpringToolSuite4 首先在spring我的项目的pom文件中增加依赖登陆http://mybatis.org/spring/官网,通过Spring Boot节点找到Maven我的项目对应的依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version></dependency>官网目前版本是2.1.3,若低于这个版本,后续应用会操作繁琐一些 未完待续,回家持续更

August 1, 2020 · 1 min · jiezi

关于springboot:SpringBoot与Mybatis整合day04

官网网址:mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/ 概述Mybatis是一个优良的长久层框架,底层基于JDBC实现与数据库的交互。并在JDBC操作的根底上做了封装和优化,它借助灵便的SQL定制,参数及后果集的映射形式,更好的适应了以后互联网技术的倒退。Mybatis框架的简略利用架构, @Mapper正文: mybatis提供的接口,形容数据层对象,零碎底层基于此注解为接口创立其实现类,而后交给spring治理 在MyBatis框架中定义SQL映射的形式有两种:办法一:通过配置映射文件写SQL(多条简单映射语句)留神点:让SQL删除语句更加强壮办法二:通过接口实现类写SQL(简略映射语句)

August 1, 2020 · 1 min · jiezi

关于springboot:SpringBoot连接池day03

概述为什么要应用连接池理论开发中应用程序与数据库交互时,“取得连贯”或“开释资源”是十分耗费系统资源的两个过程,为了解决此类性能问题,通常状况咱们采纳连接池技术来重用连贯Connection对象 常见连接池Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商须要让本人的连接池实现这个接口。而后咱们的应用程序中耦合与这个接口,便能够不便的切换不同厂商的连接池,常见的连接池有DBCP、C3P0,DRUID,HikariCP等。 整合HikariCP连接池1.创立我的项目 2.pom文件增加依赖 3.配置连贯数据库的url,username,passwordapplication.properties文件的配置 spring.datasource.url=jdbc:mysql:///dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf8spring.datasource.username=rootspring.datasource.password=root4.编写测试类

August 1, 2020 · 1 min · jiezi

关于springboot:SpringBoot简介

1.Spring Boot简介1.1 Spring Boot概述当初软件市场曾经造成肯定的规模,零碎架构的复杂度也越来越高(例如有单体架构,分布式架构,微服务架构)。软件的整个架构体系正在产生很大变动,在这种变动中,企业当初更重视技术的开箱即用,更重视技术在生态圈中的深度交融,更重视轻量级的运维。由此spring boot诞生。 1.2 Spring Boot外围个性Spring boot是一个脚手架,构建于Spring框架(Framework)根底之上,基于疾速构建理念,提供了主动配置性能,可实现其开箱即用个性(创立完一个根本的我的项目当前,可零配置或者大量配置即可运行咱们的我的项目),其外围次要有如下几个方面:起步依赖(Starter Dependency)-我的项目创立时底层帮你关联依赖。主动配置(Auto Configuration)。健康检查(Actator)-监控。其中,Spring Boot官网地址为https://spring.io/projects/spring-boot。2.Spring Boot环境配置2.1 筹备工作-工具下载1)下载JDK1.8,并进行环境变量配置2)下载最新maven(例如:apache-maven-3.6.3)网址http://maven.apache.org/3)下载sts最新版,网址https://spring.io/tools2.2 Maven根本配置1)关上maven中的setting.xml文件,并对其如下选项进行配置。 配置maven本地库(从maven近程服务器下载的资源存储到的地位) 2)配置maven私服(配置到mirrors标签外部)。 3)配置maven中的profile(配置到profiles标签外部),设置JDK编译和运行版本。 2.3 STS整合maven配置 1)启动sts进行Maven Instalations 2)Maven User Settings配置 3)我的项目工作区编码设置 2.4STS工具应用根本优化 批改STS工具内存配置,关上SpringToolSuite4.ini文件,批改堆大小 3.Spring Boot疾速入门3.1 我的项目创立及构造剖析在STS中创立Spring Boot我的项目: 3.2 我的项目启动过程剖析 SpringBoot 我的项目在启动时,首先基于启动入口类上的注解形容,进行主动配置并扫描指定包以及子包中的类进行加载,而后检测类上是否有Spring框架中指定的注解形容(例如@Component,@Controller,@Service等)。如果有,则将类交给Spring框架中的BeanFactory工厂接口的实现类对象,此工厂对象会基于反射创立Bean的实例,假如此Bean指定了生命周期办法,还会调用生命周期办法。当实例创立当前,Spring框架还会基于类的作用域形容,将实例存储到不同作用域的容器中。以实现Bean对象的迷信利用。 3.3 我的项目业务初步实现及测试业务实现:基于SpringBoot脚手架(或者架子工),通过Spring框架进行Bean对象的治理实现。 第一步:创立一个DefaultCache类,存储到src/main/java目录,而后交给spring治理。其中,@Component是Spring中用于形容Bean类的一个注解。用于通知Spring这个类的实例由Spring创立,当此对象由Spring创立和治理时,默认会将对象存储到池(Bean池)中。 第二步:增加sringboot 测试类,进行bean的获取及测试,要放在src/test/java目录中:其中: @SpringBootTest 注解用于通知spring框架,此测试类交给spring治理。@Autowired注解形容属性时,用于通知spring框架要为此属性注入一个值?(至于注入规定,前面课程缓缓增强) 第三步:代码设计及运行剖析在图中形容了DefaultCacheTests类与DefaultCache类的关系,这两个类通过指定注解(@SpringBootTest,@Component)进行了形容,其用意是通知spring框架这个两个类的实例的创立由Spring负责,并且由Spring框架基于@Autowired注解的形容实现DefaultCacheTests实例中无关DefaultCache类型的值的注入(DI)。 第四步:为对象设计作用域,设置提早加载,设置生命周期办法(理解)。 在Spring框架中,Spring为由它创立和治理的对象,设计了一些个性,例如作用域,提早加载,生命周期办法等,基于这些个性实现对Bean对象的治理。其中: @Lazy注解用于形容类,其目标是通知spring框架此类反对提早加载,通常会配合单例作用域应用。 @Scope 是Spring中用于定义Bean对象作用域的一个注解,其罕用的值有*singleton(整个内存有一份Bean实例,此实例何时创立与类的提早加载个性配置无关,此实例创立当前,生命周期会由spring框架治理),*prototype(每次获取都会创立新实例,此实例会在须要时创立与lazy个性无关,这个实例创立当前,不会交给spring治理,spring能够对其初始化,但不负责销毁。)等。 @PostConstruct 注解用于形容bean对象生命周期办法中的初始化办法,此办法会在对象的构造方法之后执行(是对象创立当前的初始化)。@PreDestroy 注解用于形容Bean对象生命周期办法中的销毁办法,此办法会在对象销毁之前执行(当作用域为prototype时,此办法不会执行)。 第五步:通过测试类测试作用域,提早加载,生命周期办法 Spring框架治理Bean对象有什么劣势!!!*Spring 是一个资源整合框架(Framework),通过spring可将很多资源(本人写的对象或第三方提供的对象,例如连接池等)整合在一起,而后进行迷信利用,以便更好的对外提供服务。*在图中,Spring框架能够为由它治理的对象(Bean)提供懒加载策略(对象临时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时能够思考内存中只有一份,prototype-应用次数少时能够用时创立,不必时销毁),生命周期办法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的无效应用。同时Spring框架还能够基于用户设计治理对象与对象的依赖关系,以升高对象与对象之间的间接耦合,进步程序的可维护性和可扩展性。 3.4 我的项目业务加强实现及测试第一步:定义业务Cache接口第二步:定义WeakCache实现Cache接口.第三步:创立或批改SoftCache,让此类也实现Cache接口第四步:单元测试类业务测试运行原理剖析 问题:1)@Autowired注解利用规定? 2)@Qualifier注解的作用是什么? @Autowired由spring框架定义,用于形容类中属性或相干办法(例如构造方法)。Spring框架在我的项目运行时如果发现由他治理的Bean对象中有应用@Autowired注解形容的属性或办法,能够依照指定规定为属性赋值(DI)。其根本规定是:首先要检测容器中是否有与属性或办法参数类型相匹配的对象,如果有并且只有一个则间接注入。其次,如果检测到有多个,还会依照@Autowired形容的属性或办法参数名查找是否有名字匹配的对象,有则间接注入,没有则抛出异样。最初,如果咱们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还能够应用@Qualifier注解对其属性或参数进行形容(此注解必须配合@Autowired注解应用)。 4.Spring Boot大节总结4.1 重难点剖析Spring boot 是什么? (框架,也能够看成是框架脚手架,做了架子工要做的事件-搭建我的项目根底骨架的工作人员)Spring boot 外围劣势?(启动依赖,主动配置-开箱即用,健康检查-系统监控)Spring boot 我的项目的创立形式?( https://start.spring.io)Spring boot我的项目启动时,Bean的初始化过程是怎么的?(查找,加载,读和存储配置,创立和存储实例对象)Spring boot 我的项目启动时,Bean对象的依赖注入过程是怎么的?(标记,查找,注入)Spring 框架中的Bean对象有什么个性?(提早加载,作用域,生命周期办法)Spring 框架中单例(singleton)作用域对象特点,利用场景(频繁用)?Spring 框架中多例(prototype)作用域对象特点,利用场景(稀少用)?4.2 FAD剖析1.Maven工具(我的项目构建工具)从哪里下载?(maven.apache.org) ...

July 30, 2020 · 1 min · jiezi

关于springboot:SpringBoot为Bean赋予的特点day02

1.1利用场景1.2外围特色起步依赖(Starter Dependency)-我的项目创立时底层帮你关联依赖。 主动配置(Auto Configuration)。 健康检查(Actator)-监控。 1.3Maven的配置1.4我的项目构造剖析(上一篇)1.5我的项目的启动类2.1如何判断对象什么时候创立(日志,断点)2.2SpringBoot和Spring的关系--什么是Spring Spring框架为开发Java应用程序提供了全面的基础架构反对。它蕴含一些很好的性能,如依赖注入和开箱即用的模块,如: Spring JDBC 、Spring MVC 、Spring Security、 Spring AOP 、Spring ORM 、Spring Test 这些模块缩短应用程序的开发工夫,进步了利用开发的效率 --什么是Spring Boot Spring Boot基本上是Spring框架的扩大,它打消了设置Spring应用程序所需的XML配置,为更快,更高效的开发生态系统铺平了路线 2.3为什么要应用springBoot2.3.1@Lazy--提供提早加载的办法,节俭资源 *提早加载的利用场景应用多个对象或者大数据结构时,一种晋升其性能的形式是使用提早加载或赋值(来实现)。将费时的操作尽可能的缩短的想法,从未实现。节俭内存资源*单元测试办法的利用场景 不能用在private下. 容许抛出异样 不容许有返回值 不能有参数列表Spring 是一个资源整合框架(Framework),通过spring可将很多资源(本人写的对象或第三方提供的对象,例如连接池等)整合在一起,而后进行迷信利用,以便更好的对外提供服务。 Spring框架能够为由它治理的对象(Bean)提供懒加载策略(对象临时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时能够思考内存中只有一份,prototype-应用次数少时能够用时创立,不必时销毁),生命周期办法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的无效应用。同时Spring框架还能够基于用户设计治理对象与对象的依赖关系,以升高对象与对象之间的间接耦合,进步程序的可维护性和可扩展性。 Bean对象的注解@Component只能形容类,标注一个类为Spring容器的Bean(默认为类名首字母小写,如果对应的启动类加@Bean标注,则会定义两次Bean名字,从而报错)相当于候选类 @Scope是Spring中用于定义Bean对象作用域的一个注解, 其罕用的值有: singleton(整个内存有一份Bean实例,此实例何时创立与类的提早加载个性配置无关,此实例创立当前,生命周期会由spring框架治理), prototype(每次获取都会创立新实例,此实例会在须要时创立与lazy个性无关,这个实例创立当前,不会交给spring治理,spring能够对其初始化,但不负责销毁。不在Bean池里)等。 @Lazy注解用于形容类,其目标是通知spring框架此类反对提早加载,通常会配合单例作用域应用。其参数为true(默认)和false(无意义) @PostConstruct 注解用于形容bean对象生命周期办法中的初始化办法,此办法会在对象的构造方法之后执行。 @PreDestroy 注解用于形容Bean对象生命周期办法中的销毁方(多例作用域(prototype)时不执行,因为不在Bean池中) 测试类的注解@SpringBootTest示意一个SpringBoot测试类 启动类的注解@Bean个别用于第三方资源的注入 @Scope @Lazy ** @Autowired注解利用规定(一个时间接注入,多个时须要指定) @Qualifier注解的作用(配合@Autowired应用,只能形容参数属性) @Autowired由spring框架定义,用于形容类中属性或相干办法(例如构造方法)。Spring框架在我的项目运行时如果发现由他治理的Bean对象中有应用@Autowired注解形容的属性或办法,能够依照指定规定为属性赋值(DI)。其根本规定是:首先要检测容器中是否有与属性或办法参数类型相匹配的对象,如果有并且只有一个则间接注入。其次,如果检测到有多个,还会依照@Autowired形容的属性或办法参数名查找是否有名字匹配的对象,有则间接注入,没有则抛出异样。最初,如果咱们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还能够应用@Qualifier注解对其属性或参数进行形容(此注解必须配合@Autowired注解应用)。

July 29, 2020 · 1 min · jiezi

关于springboot:SpringBoot为Bean赋予的特点day02

1.1利用场景1.2外围特色起步依赖(Starter Dependency)-我的项目创立时底层帮你关联依赖。 主动配置(Auto Configuration)。 健康检查(Actator)-监控。 1.3Maven的配置1.4我的项目构造剖析(上一篇)1.5我的项目的启动类2.1如何判断对象什么时候创立(日志,断点)2.2SpringBoot和Spring的关系--什么是Spring Spring框架为开发Java应用程序提供了全面的基础架构反对。它蕴含一些很好的性能,如依赖注入和开箱即用的模块,如: Spring JDBC 、Spring MVC 、Spring Security、 Spring AOP 、Spring ORM 、Spring Test 这些模块缩短应用程序的开发工夫,进步了利用开发的效率 --什么是Spring Boot Spring Boot基本上是Spring框架的扩大,它打消了设置Spring应用程序所需的XML配置,为更快,更高效的开发生态系统铺平了路线 2.3为什么要应用springBoot2.3.1@Lazy--提供提早加载的办法,节俭资源 *提早加载的利用场景应用多个对象或者大数据结构时,一种晋升其性能的形式是使用提早加载或赋值(来实现)。将费时的操作尽可能的缩短的想法,从未实现。节俭内存资源*单元测试办法的利用场景 不能用在private下. 容许抛出异样 不容许有返回值 不能有参数列表Spring 是一个资源整合框架(Framework),通过spring可将很多资源(本人写的对象或第三方提供的对象,例如连接池等)整合在一起,而后进行迷信利用,以便更好的对外提供服务。 Spring框架能够为由它治理的对象(Bean)提供懒加载策略(对象临时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时能够思考内存中只有一份,prototype-应用次数少时能够用时创立,不必时销毁),生命周期办法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的无效应用。同时Spring框架还能够基于用户设计治理对象与对象的依赖关系,以升高对象与对象之间的间接耦合,进步程序的可维护性和可扩展性。 Bean对象的注解@Component只能形容类,标注一个类为Spring容器的Bean(默认为类名首字母小写,如果对应的启动类加@Bean标注,则会定义两次Bean名字,从而报错)相当于候选类 @Scope是Spring中用于定义Bean对象作用域的一个注解, 其罕用的值有: singleton(整个内存有一份Bean实例,此实例何时创立与类的提早加载个性配置无关,此实例创立当前,生命周期会由spring框架治理), prototype(每次获取都会创立新实例,此实例会在须要时创立与lazy个性无关,这个实例创立当前,不会交给spring治理,spring能够对其初始化,但不负责销毁。不在Bean池里)等。 @Lazy注解用于形容类,其目标是通知spring框架此类反对提早加载,通常会配合单例作用域应用。其参数为true(默认)和false(无意义) @PostConstruct 注解用于形容bean对象生命周期办法中的初始化办法,此办法会在对象的构造方法之后执行。 @PreDestroy 注解用于形容Bean对象生命周期办法中的销毁方(多例作用域(prototype)时不执行,因为不在Bean池中) 测试类的注解@SpringBootTest示意一个SpringBoot测试类 启动类的注解@Bean个别用于第三方资源的注入 @Scope @Lazy ** @Autowired注解利用规定(一个时间接注入,多个时须要指定) @Qualifier注解的作用(配合@Autowired应用,只能形容参数属性) @Autowired由spring框架定义,用于形容类中属性或相干办法(例如构造方法)。Spring框架在我的项目运行时如果发现由他治理的Bean对象中有应用@Autowired注解形容的属性或办法,能够依照指定规定为属性赋值(DI)。其根本规定是:首先要检测容器中是否有与属性或办法参数类型相匹配的对象,如果有并且只有一个则间接注入。其次,如果检测到有多个,还会依照@Autowired形容的属性或办法参数名查找是否有名字匹配的对象,有则间接注入,没有则抛出异样。最初,如果咱们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还能够应用@Qualifier注解对其属性或参数进行形容(此注解必须配合@Autowired注解应用)。

July 29, 2020 · 1 min · jiezi

关于springboot:Trainee0722第一个任务使用jar包captcha实现验证码

尽管老大说这是一个特简略的小我的项目,然而我这个没有接触过springboot的人感觉难的批爆,最终历时四个小时才做进去。 需要实现一个小东西,用captcha jar包做一个demo,实现登陆的验证码,用以验证一下captcha的设置问题。 难点在校期间只是做一些算法方面的问题,没有接触过框架常识。始终用的是Eclipse,当初要改用IDEA。Step1:入手创立Spring Boot我的项目创立Spring Boot我的项目有三种办法,见【尚硅谷Spring Boot】入门5 ~ 8:HelloWorld,应用IDEA,中的Spring Initializr间接创立Spring Boot我的项目最为不便。 关上IDEA,点击Create New Project ➡ Spring Initializr,如图所示:在这里抉择好JDK版本。这一步要留神Java Version的抉择。按需抉择,这里我创立Spring Web我的项目:这一步留神Spring Boot版本的抉择。这里在界面左上角能够搜寻并增加须要增加的依赖(Dependencies)如Lombok、Thymeleaf等,当然依赖也能够在生成我的项目之后在pom.xml文件中手动增加。 给我的项目取个名字吧!创立胜利后这些文件能够删除:胜利:导入kaptcha依赖在pom.xml文件中增加: <!-- Kaptcha --><dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version></dependency>Step2:剖析有两种形式在Spring Boot中应用kaptcha: 应用.xml的配置形式配置生成kaptcha的bean对象,在启动类上应用@ImportResource引入这个xml文件,在controller中注入其对象并应用;把kaptcha作为工程的一个类,加上@Configuration注解,在返回kaptcha的办法中加上@Bean注解,再在controller中注入其对象。Step3.1:办法1①创立KaptchaConfig.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha"> <property name="config"> <bean class="com.google.code.kaptcha.util.Config"> <constructor-arg type="java.util.Properties"> <props> <!--是否应用边框--> <prop key = "kaptcha.border ">yes</prop> <!--边框色彩--> <prop key="kaptcha.border.color">105,179,90</prop> <!--验证码字体色彩--> <prop key="kaptcha.textproducer.font.color">blue</prop> <!--验证码图片的宽度--> <prop key="kaptcha.image.width">100</prop> <!--验证码图片的高度--> <prop key="kaptcha.image.height">50</prop> <!--验证码字体的大小--> <prop key="kaptcha.textproducer.font.size">27</prop> <!--验证码保留在session的key--> <prop key="kaptcha.session.key">code</prop> <!--验证码输入的字符长度--> <prop key="kaptcha.textproducer.char.length">4</prop> <!--验证码的字体设置--> <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop> <!--验证码的取值范畴--> <prop key="kaptcha.textproducer.char.string">0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ</prop> <!--图片的款式--> <prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.WaterRipple</prop> <!--烦扰色彩,非法值: r,g,b 或者 white,black,blue.--> <prop key="kaptcha.noise.color">black</prop> <!--烦扰实现类--> <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.DefaultNoise</prop> <!--背景色彩突变,开始色彩--> <prop key="kaptcha.background.clear.from">185,56,213</prop> <!--背景色彩突变,完结色彩--> <prop key="kaptcha.background.clear.to">white</prop> <!--文字距离--> <prop key="kaptcha.textproducer.char.space">3</prop> </props> </constructor-arg> </bean> </property> </bean></beans>②在启动类上引入这个文件@SpringBootApplication@ImportResource(locations={"classpath:KaptchaConfig.xml"})public class CaptchaApplication { public static void main(String[] args) { // SpringApplication SpringApplication.run(CaptchaApplication.class, args); }}③编写Controller@RestControllerpublic class KaptchaController { // 在Controller中注入defaultKaptcha @Autowired DefaultKaptcha defaultKaptcha; //获取验证码 @RequestMapping("/getKaptcha") public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { byte[] captchaChallengeAsJpeg = null; ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { //生产验证码字符串并保留到session中 String createText = defaultKaptcha.createText(); httpServletRequest.getSession().setAttribute("verifyCode", createText); //应用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中 BufferedImage challenge = defaultKaptcha.createImage(createText); ImageIO.write(challenge, "jpg", jpegOutputStream); } catch (IllegalArgumentException e) { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); return; } //定义response输入类型为image/jpeg类型,应用response输入流输入图片的byte数组 captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); httpServletResponse.setHeader("Cache-Control", "no-store"); httpServletResponse.setHeader("Pragma", "no-cache"); httpServletResponse.setDateHeader("Expires", 0); httpServletResponse.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); }} ...

July 29, 2020 · 2 min · jiezi

关于springboot:SpringBoot-项目创建

SpringBoot我的项目环境初始化下载、装置、配置JDK(这里抉择JDK8版本)下载、解压、配置maven(这里抉择3.6.3版本)下载、解压、配置STS(这里抉择4.7.0版本)阐明:对于环境下载,装置配置,本人通过官网或搜索引擎查问实现。 SpringBoot我的项目创立过程剖析及实现基于STS内置start创立第一步:关上sts软件,快捷键ctrl+n关上新建窗口,如图所示: 第二步:输出我的项目相干信息,如图所示: 第三步:抉择SpringBoot版本,如图所示: 第四步:我的项目构造展现,我的项目创立完当前的构造如下: 基于浏览器(Browser)创立第一步:关上浏览器输出start.spring.io,而后输出我的项目信息,进行我的项目构建,如图所示: 第二步:将构建并下载下来的我的项目进行解压,如图所示: 第三步:将解压好的我的项目导入到sts中,如图所示: 第四部步:我的项目构造展现,如图所示: 基于STS一般maven形式创立第一步:创立一般maven我的项目,快捷键ctrl+n 搜maven,如图所示: 第二步:抉择我的项目骨架,如图所示: 第三步:输出像我的项目信息,如图所示: 第四步:我的项目构造展现,如图所示: 第五步:将已有我的项目的pom文件,我的项目启动类,配置文件拷贝到maven工程中,并进行适当批改,例如批改一下pom文件中项目名称.

July 29, 2020 · 1 min · jiezi

关于springboot:SpringBoot-简介

Spring Boot 背景剖析JAVAEE利用体系中沉重的配置、低下的开发效率、高难度的三方集成,简单的部署流程等等始终被开发人员所诟病。即便是应用Spring这样的轻量级的资源整合框架,在实现其绝对比拟多的资源整合时,仍旧须要大量的手动依赖治理,简单的XML配置(还常常没有提醒)。还有就是当初的软件生态利用也曾经造成肯定的规模,零碎架构正在从单体架构,分布式架构,逾越到微服务架构。随着整个架构体系的变动,企业对技术的要求也在变动,当初的企业更重视技术的开箱即用,更重视技术在生态圈中的深度交融,更重视轻量级的运维。由此由此spring boot诞生。 Spring Boot 要解决什么问题Spring Boot是由Pivotal团队提供的全新的Java软件开发框架(很多人当初把它了解为一个脚手架),其设计目标是用来简化Spring我的项目的初始搭建以及开发过程。该框架应用了特定的注解形式来进行配置,从而使开发人员不再须要大量的xml配置。不再须要大量的手动依赖治理。Spring Boot基于疾速构建理念,通过约定大于配置,开箱即用的形式,心愿可能在蓬勃发展的疾速利用开发畛域成为其领导者。 Spring Boot 有哪些外围的要害个性起步依赖(Starter Dependency)。主动配置(Auto Configuration)。健康检查(Actator)-监控。嵌入式服务(Tomcat,Jetty).

July 28, 2020 · 1 min · jiezi

关于springboot:SpringBoot2-整合MinIO中间件实现文件便捷管理

本文源码:GitHub·点这里 || GitEE·点这里 一、MinIO简介1、根底形容MinIO是一个开源的对象存储服务。适宜于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件能够是任意大小,从几kb到最大5T不等。 MinIO是一个十分轻量的服务,能够很简略的和其余利用的联合,相似 NodeJS, Redis 或者 MySQL。 2、存储机制MinIO应用按对象的嵌入式擦除编码爱护数据,该编码以汇编代码编写,可提供最高的性能。MinIO应用Reed-Solomon代码将对象划分为n/2个数据和n / 2个奇偶校验块-只管能够将它们配置为任何所需的冗余级别。 这意味着在12个驱动器设置中,将一个对象分片为6个数据和6个奇偶校验块。即便失落了多达5个((n/2)–1)个驱动器(无论是奇偶校验还是数据),依然能够从其余驱动器牢靠地重建数据。MinIO的实现可确保即便失落或无奈应用多个设施,也能够读取对象或写入新对象。最初,MinIO的擦除代码位于对象级别,并且能够一次修复一个对象。 二、MinIO环境搭建1、安装包下载https://dl.min.io/server/minio/release/linux-amd64/minio倡议应用某雷下载,速度会快点,下载包上传到/opt/minioconfig/run目录下。 2、创立数据存储目录mkdir -p /data/minio/data3、服务启动启动并指定数据寄存地址 /opt/minioconfig/run/minio server /data/minio/data/输入日志 Endpoint: http://localhost:9000 http://127.0.0.1:9000 AccessKey: minioadmin SecretKey: minioadmin这里就是登录地址和账号密码。 三、整合SpringBoot环境1、根底依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>3.0.12</version></dependency>2、根底配置配置因素:地址和端口,登录名,明码,HTML存储桶,图片存储桶。 minio: endpoint: http://192.168.72.133:9000 accessKey: minioadmin secretKey: minioadmin bucketNameHtml: html bucketNameImage: image文件上传之后,能够基于文件地址间接拜访,然而须要在MinIO中配置文件的读写权限: 3、配置参数类@Component@ConfigurationProperties(prefix = "minio")public class ParamConfig { private String endpoint ; private String accessKey ; private String secretKey ; private String bucketNameHtml ; private String bucketNameImage ; // 省略 get 和 set办法}4、基于MinIO配置类封装MinIO客户端连贯工具,文件上传的根底办法,返回文件在MinIO服务上的URL地址。 ...

July 27, 2020 · 2 min · jiezi

关于springboot:SpringBoot2-整合MinIO中间件实现文件便捷管理

本文源码:GitHub·点这里 || GitEE·点这里 一、MinIO简介1、根底形容MinIO是一个开源的对象存储服务。适宜于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件能够是任意大小,从几kb到最大5T不等。 MinIO是一个十分轻量的服务,能够很简略的和其余利用的联合,相似 NodeJS, Redis 或者 MySQL。 2、存储机制MinIO应用按对象的嵌入式擦除编码爱护数据,该编码以汇编代码编写,可提供最高的性能。MinIO应用Reed-Solomon代码将对象划分为n/2个数据和n / 2个奇偶校验块-只管能够将它们配置为任何所需的冗余级别。 这意味着在12个驱动器设置中,将一个对象分片为6个数据和6个奇偶校验块。即便失落了多达5个((n/2)–1)个驱动器(无论是奇偶校验还是数据),依然能够从其余驱动器牢靠地重建数据。MinIO的实现可确保即便失落或无奈应用多个设施,也能够读取对象或写入新对象。最初,MinIO的擦除代码位于对象级别,并且能够一次修复一个对象。 二、MinIO环境搭建1、安装包下载https://dl.min.io/server/minio/release/linux-amd64/minio倡议应用某雷下载,速度会快点,下载包上传到/opt/minioconfig/run目录下。 2、创立数据存储目录mkdir -p /data/minio/data3、服务启动启动并指定数据寄存地址 /opt/minioconfig/run/minio server /data/minio/data/输入日志 Endpoint: http://localhost:9000 http://127.0.0.1:9000 AccessKey: minioadmin SecretKey: minioadmin这里就是登录地址和账号密码。 三、整合SpringBoot环境1、根底依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>3.0.12</version></dependency>2、根底配置配置因素:地址和端口,登录名,明码,HTML存储桶,图片存储桶。 minio: endpoint: http://192.168.72.133:9000 accessKey: minioadmin secretKey: minioadmin bucketNameHtml: html bucketNameImage: image文件上传之后,能够基于文件地址间接拜访,然而须要在MinIO中配置文件的读写权限: 3、配置参数类@Component@ConfigurationProperties(prefix = "minio")public class ParamConfig { private String endpoint ; private String accessKey ; private String secretKey ; private String bucketNameHtml ; private String bucketNameImage ; // 省略 get 和 set办法}4、基于MinIO配置类封装MinIO客户端连贯工具,文件上传的根底办法,返回文件在MinIO服务上的URL地址。 ...

July 27, 2020 · 2 min · jiezi

关于springboot:mica-204GA-发布新增micaxss组件

mica(云母)mica 由如梦技术外部的 lutool(撸秃) 演变而来。lutool 诞生于 2017 年,受 jhipster 启发逐步形成一个微服务的外围集。 因 lutool 名称与性能不太合乎,故在2019年开源时将其改名为 mica(云母),寓意为云服务的基石。 mica 2.x外围依赖mica 基于 java 8,没有历史包袱,反对传统 Servlet 和 Reactive(webflux)。采纳 mica-auto 主动生成 spring.factories 和 spring-devtools.properties 配置,仅依赖 Spring boot、Spring cloud 全家桶,无第三方依赖。市面上鲜有的微服务外围组件。 依赖版本Spring Boot2.3.xmica 2.0.4-GA 更新阐明???? 欠缺应用文档.✨ mica-http 增加 pathParam 办法。✨ mica-ip2region IpInfo 增加 getAddress 办法。✨ 增加 mica-xss 模块.✨ mica-http 应用 CompletableFuture 优化异步 github #29 。✨ mica-core BeanUtil add deepClone method.✨ mica-core INetUtil 增加内网 ip 判断。✨ mica-spider 修复 readme,简化应用。⬆️ 降级 spring cloud 到 Hoxton.SR6。⬆️ 降级 spring boot 到 2.3.2.RELEASE。⬆️ 降级 knife4j 到 2.0.4。⬆️ 降级 mica-auto 到 1.2.5。新增 mica-xss 组件基于 Jsoup 的 xss 过滤。对字符串类型的表单数据进行 xss 解决。对字符串类型的 json 数据进行 xss 解决。提供路由和控制器办法级别的放行规定和注解。文档mica 源码 Github:https://github.com/lets-micamica 源码 Gitee(码云):https://gitee.com/596392912/mica文档地址(官网):https://www.dreamlu.net/mica2x/index.html文档地址(语雀-可关注订阅):https://www.yuque.com/dreamlu示例我的项目:https://github.com/lets-mica/mica-example关注咱们扫描下面二维码,更多精彩内容每天举荐! ...

July 26, 2020 · 1 min · jiezi

关于springboot:搞事情Spring-Boot今天一口气发布三个版本

学无止境?本文已被 https://www.yourbatman.cn 收录,外面一并有Spring技术栈、MyBatis、JVM、中间件等小而美的专栏供以收费学习。关注公众号【BAT的乌托邦】一一击破,深刻把握,回绝浅尝辄止。 前言各位好,我是A哥(YourBatman)。明天是2020-07-25,上午我正从https://start.spring.io筹备down一个工程下来的时候,关上页面发现默认选中的Spring Boot版本号是2.3.2:并非我刻意的去找到这个变动,而是因为我昨天 down下来的工程应用的Spring Boot版本是2.3.1,印象还在,所以明天一下子就发现了差别。 既然降级了(尽管是小版本号),那就去官网楼一眼呗。不看不晓得,一看还真让发现些内容:Spring Boot在同一天(2020-07-25)一口气公布了三个版本,这是要搞事件啊? 小贴士:本文所有工夫若未做非凡阐明,指的均是北京工夫注释Spring Boot目前还处于Active沉闷的分支共有三个:因而就在明天,同一天里Spring Boot对它的这三条线做了更新: Spring Boot 2.3.1 -> Spring Boot 2.3.2Spring Boot 2.2.8 -> Spring Boot 2.2.9Spring Boot 2.1.15 -> Spring Boot 2.1.16此次发版,间隔上次正式发版(不辨别分支)已足足有44天之久。 有哪些降级?参考github上的Release详情,三个分支都有如下三方面的改良: ???? 修复bug???? 文档同步???? 降级依赖???? 修复bug小版本号的降级,最重要的使命就是修复bug,这是它存在的意义。针对这三个版本,各自的bug修复总数如下: 2.3.2:34个。遥遥领先2.2.9:10个。2.1.16:1个。能发现法则吧,版本越新,bug越多,这是合乎常理的。另外,从小版本号里能晓得:2.1.x版本都修复16次bug了,而2.3.x才第2次修复,正处于bug井喷阶段呢。所以一味的追新的话,还需谨慎哈。 兴许你会吐槽,Spring Boot这啥编码程度,咋这么多bug?其实非也,个数虽多(其实也还好),但每一个都是非重大bug,影响甚微,无需少见多怪。 另外,从bug的起因上来看,不少bug是各个版本都有的共性问题。比方2.1.x版本那个惟一的bug,其它两个版本均有: ???? 文档同步此part用于对文档上的扭转做出一些阐明,比方文字描述谬误、排班不正确等等。举例本次的一个修复: 修复前:修复后:不得不说,这老外还挺较真(挺认真)的。 ???? 降级依赖因为是小版本的降级,因而对应的依赖也是小版本升级。举例: Tomcat降级到9.0.37Spring Framework降级到5.2.8(此版本4天前公布)值得注意的是,拿Spring Framework的降级举例:Spring Boot的2.2.x和2.3.x都是降级到了5.2.8版本,而Spring Boot的2.1.x分支依赖的是Spring Framework 5.1.17版本哦。 除此之外,Spring Boot它的最新版本,也就是2.3.2里还新增了3个新个性,理解一下: 改良 Kubernates Liveness/Readiness 衰弱指标和探针配置增加运行镜像选项用于Docker镜像构建减少对reactive Elasticsearch的健康检查小贴士:小版本号的降级是能够新增这种很小的性能点的,但不容许新增大性能三个版本外围依赖的区别Spring Boot目前沉闷的分支有3个,也就是这三个主线版本。那么他们三在外围依赖上有啥区别呢?A哥特意翻材料帮你整顿了一下,绘制如下表: 阐明:因为表格兼容性不太好,所以我以图片形式展现 对于1.5.x和2.0.x版本这两个分支曾经是古董分支了: stale中文意思:不陈腐的,老掉牙的,没有新意的它们早已死于非命,最初一个版本和公布工夫为: 1.5.22.RELEASE,2019.082.0.9.RELEASE,2019.04有意思的是,2.0.x版本的生命周期十分的短暂,简直刚好一年(2018.3 - 2019.4)。然而不可否认2.0.x版本是具备划时代意义的,在1.5.x的根底上垮了一大步,上了一个大台阶。 ...

July 26, 2020 · 1 min · jiezi

关于springboot:springboot2配置文件定义username内容失效问题探究

前言在敌人的我的项目有个自定义配置文件user.yml,其内容如下 user: userId: 1 name: 张三 email: zhangsan@qq.com其映射实体内容为如下 @Data@AllArgsConstructor@NoArgsConstructor@Builder@PropertySource(value = "user.yml",encoding = "utf-8",factory = CustomYmlPropertySourceFactory.class)@ConfigurationProperties(prefix = "user")@Configurationpublic class User { private String name; private Long userId; private String email;}我的项目启动后,输入的user内容为 User(name=Administrator, userId=1, email=zhangsan@qq.com)很显著name的内容不是咱们想要的 排查从跟踪的源码能够发现有个systemProperties配置排在user.yml后面。systemProperties这是个啥货色,见名之意,这显著就是零碎属性配置。而systemProperties外面又有啥内容,咱们持续跟踪下从源码能够看出systemProperties外面有个key为user.name,value为Administrator。 从这边咱们能够看出咱们控制台打印进去的内容其实是systemProperties的内容。由此咱们能够推断出当零碎变量和自定义配置变量都有一样的key时,将以零碎变量的值为准。 看到这边兴许有敌人说你这是在胡言乱语,就凭这个景象就得出这个论断。那好为了证实这个论断,咱们不得持续断点排查上来。不过在断点之前,咱们去spring官网溜溜,看有没有啥播种。进官网咱们能够看到有这么一段话这段话的意思是默认状况下,零碎属性优先于环境变量。 因而,如果在调用env.getProperty(“ my-property”)的过程中在两个中央都同时设置了my-property属性,则零碎属性值“ wins”并返回。 请留神,属性值不会合并,而是会被后面的条目齐全笼罩。 看吧,官网它本人也这么说 如果咱们想要自定义的属性优于零碎属性,要怎么做这段也是从官网截图来的,其意思是整个机制是可配置的。 兴许您具备要集成到此搜寻中的自定义属性源。 为此,实现并实例化您本人的PropertySource并将其增加到以后环境的PropertySources集中 ConfigurableApplicationContext ctx = new GenericApplicationContext();MutablePropertySources sources = ctx.getEnvironment().getPropertySources();sources.addFirst(new MyPropertySource());这个是官网解法。 我这边在提供2种解法。 bean初始化之前,批改属性文件加载程序在bean初始化后,变更bean的属性值其实现代码如下 ntBeanFactoryPostProcesser implements BeanFactoryPostProcessor, ApplicationContextAware, BeanPostProcessor { private ApplicationContext applicationContext; @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { //办法三:在bean初始化后,变更bean的属性值// if("user".equals(beanName)){// User user = (User)bean;// System.out.println("----------------before---------------------");// System.out.println("user-->"+user);// System.out.println("----------------after---------------------");// String propertySourceName = "user.yml";// PropertySource propertySource = getPropertySource(propertySourceName);// if(!ObjectUtils.isEmpty(propertySource)){// user.setName(String.valueOf(propertySource.getProperty("user.name")));// }// System.out.println("user-->"+user);//// } return bean; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { printPropertySourceNames(); String propertySourceName = "user.yml"; PropertySource propertySource = getPropertySource(propertySourceName); if(!ObjectUtils.isEmpty(propertySource)){ //办法一 bean初始化之前,批改属性文件加载程序 getEnvironment().getPropertySources().remove(propertySourceName); getEnvironment().getPropertySources().addFirst(propertySource); } // 办法二 新增一个PropertySource,并把他的加载程序置为第一位// Map<String, Object> propertiesSource = new HashMap<>();// propertiesSource.put("user.name", "张三");// PropertySource newPropertySource = new MapPropertySource("newPropertySource", propertiesSource);// getEnvironment().getPropertySources().addFirst(newPropertySource); } private PropertySource getPropertySource(String propertySourceName){ return getEnvironment().getPropertySources().get(propertySourceName); } private AbstractEnvironment getEnvironment(){ return (AbstractEnvironment)applicationContext.getEnvironment(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } private void printPropertySourceNames(){ getEnvironment().getPropertySources().stream().forEach(p-> System.out.println(p.getName())); }}改完后,咱们看下控制台此时输入的内容为 ...

July 24, 2020 · 1 min · jiezi

关于springboot:使用shiro进行登录认证案例1

开发步骤1.导入相干依赖(一共10个)2.控制器编写2个办法(注册和登录)3.自定义认证受权处理器,继承AuthorizingRealm类4.实现doGetAuthenticationInfo认证办法5.解决认证办法5.1.获取用户名5.2.调用service成判断用户是否存在5.3.判断用户的状态5.4.返回一个SimpleAuthenticationInfo认证对象6.编写shiro配置类(ShiroConfig)6.1配置ShiroFilterFactoryBean注入SecurityManager6.2配置SecurityManager注入咱们自定义的认证处理器(ShiroRealm)6.3.配置自定义认证处理器(ShiroRealm)注入自定义明码匹配器(CredentialsMatcher)7.自定义明码匹配器(继承SimpleCredentialsMatcher类),重写doCredentialsMatch办法7.1自定义加密解密工具类实现7.2应用BCryptPasswordEncoder类实现8.配置application.yml文件8.1MySQL数据源8.2通用mapper 的代理类门路9.异样信息相应解决(可有可无)10.测试性能,注册和登录1.pom依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <!--测试启动器--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--springMVC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--整合Mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!--mysql数据源--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--通用mapper--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <!--spring整合shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--日志打印--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!--lombok懒人依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--JSON转换--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.71</version> </dependency> <!--加密--> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.3.3.RELEASE</version> </dependency> </dependencies></project>2.controller的2个办法:增加和登录package com.huacheng.controller;import com.huacheng.domain.User;import com.huacheng.response.ResponseVO;import com.huacheng.service.UserService;import com.huacheng.util.PasswordUtil;import com.huacheng.util.ResultUtil;import lombok.extern.log4j.Log4j2;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@Log4j2@RestControllerpublic class LoginController { @Autowired private UserService userService; /** * 登录 * * @param username * @param password * @param rememberMe * @return */ @RequestMapping("/login") public ResponseVO login(String username, String password, Boolean rememberMe) { UsernamePasswordToken token = null; try { //登录 token = new UsernamePasswordToken(username, password, false); //获取以后的登录对象 Subject currentUser = SecurityUtils.getSubject(); currentUser.login(token); return ResultUtil.success("登录胜利:"+username+"用户欢迎您"); } catch (Exception e) { log.info("登录失败用户名{}", username, e); token.clear(); return ResultUtil.error(e.getMessage()); } } @RequestMapping("/add") public ResponseVO add(User user) { try { userService.add(user); } catch (Exception e) { log.info("新增失败:{}", user); return ResultUtil.error("增加失败"); } log.info("新增用户:{}", user); return ResultUtil.success("增加胜利"); }}3.编写自定义认证受权处理器(ShiroRealm)package com.huacheng.realms;import com.huacheng.domain.User;import com.huacheng.service.UserService;import com.huacheng.util.PasswordUtil;import lombok.SneakyThrows;import lombok.extern.log4j.Log4j2;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.print.DocFlavor;@Log4j2//@Componentpublic class ShiroRealm extends AuthorizingRealm { @Autowired private UserService userService; /** * 受权的办法 * * @param principal * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { return null; } /** * 认证的办法 * * @param token * @return */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { //1.获取用户名 String username = (String) token.getPrincipal(); User user = userService.findUserByUsername(username); //2.判断用户的账号是否存在 if (user == null) { log.info("用户名或者明码谬误user:{}", user); throw new UnknownAccountException("用户名或者明码谬误"); } //3.判断用户的状态是否可用 if (user.getStatus() == 0) { log.info("帐号已被锁定,禁止登录,user:{}", user); throw new LockedAccountException("帐号已被锁定,禁止登录!"); } //4.返回一个认证对象 log.info("登录胜利:{}", user.getUsername() + "用户欢迎您"); return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName()); }}4.编写shiro配置类(ShiroConfig)package com.huacheng.config;import com.huacheng.credentials.CredentialsMatcher;import com.huacheng.realms.ShiroRealm;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必须设置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); /* // 如果不设置默认会主动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录胜利后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index.html");*/ return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager(ShiroRealm myRealms) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //注入咱们自定义的认证受权处理器 securityManager.setRealm(myRealms); return securityManager; } @Bean public ShiroRealm shiroRealm(CredentialsMatcher credentialsMatcher) { ShiroRealm myRealms = new ShiroRealm(); //注入自定义的明码匹配器 myRealms.setCredentialsMatcher(credentialsMatcher); return myRealms; }}5.自定义明码匹配器(这里我用2中形式都可行)package com.huacheng.credentials;import com.huacheng.util.PasswordUtil;import lombok.extern.java.Log;import lombok.extern.log4j.Log4j2;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.stereotype.Component;/** * Shiro-明码凭证匹配器(验证明码有效性) */@Log4j2@Componentpublic class CredentialsMatcher extends SimpleCredentialsMatcher { @Autowired private BCryptPasswordEncoder passwordEncoder; @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken utoken = (UsernamePasswordToken) token; //1.取得用户输出的明文明码 String loginPassword = new String(utoken.getPassword()); //2.取得数据路的密文明码 String dbPassword = (String) info.getCredentials(); //3.进行明码的比对 //第一种形式,应用本人的加密解密办法比对明码 /* String decryptPassword = null; try { decryptPassword = PasswordUtil.decrypt(dbPassword, utoken.getUsername()); } catch (Exception e) { log.info("明码解密失败{}", loginPassword); throw new RuntimeException("明码解密失败"); } if (!decryptPassword.equals(loginPassword)) { throw new IncorrectCredentialsException("用户名或者明码谬误"); }*/ //第二种形式,应用BCryptPasswordEncoder进行解密 if (!passwordEncoder.matches(loginPassword, dbPassword)) { throw new IncorrectCredentialsException("用户名或者明码谬误"); } return true; }}6.对立异样解决的控制器package com.huacheng.controller;import com.huacheng.enums.ResponseStatus;import com.huacheng.exception.Myexception;import com.huacheng.response.ResponseVO;import com.huacheng.util.CommonConst;import com.huacheng.util.ResultUtil;import lombok.extern.slf4j.Slf4j;import org.apache.shiro.authc.IncorrectCredentialsException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import java.lang.reflect.UndeclaredThrowableException;/** * 对立异样解决类<br> * 捕捉程序所有异样,针对不同异样,采取不同的解决形式 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @website https://www.zhyd.me * @date 2018/4/24 14:37 * @since 1.0 */@Slf4j@ControllerAdvicepublic class ExceptionHandleController { @ExceptionHandler(value = Exception.class) @ResponseBody public ResponseVO handle(Throwable e) { if (e instanceof Myexception) { return ResultUtil.error(e.getMessage()); } if (e instanceof UndeclaredThrowableException) { e = ((UndeclaredThrowableException) e).getUndeclaredThrowable(); } ResponseStatus responseStatus = ResponseStatus.getResponseStatus(e.getMessage()); if (responseStatus != null) { log.error(responseStatus.getMessage()); return ResultUtil.error(responseStatus.getCode(), responseStatus.getMessage()); } e.printStackTrace(); // 打印异样栈 return ResultUtil.error(CommonConst.DEFAULT_ERROR_CODE, ResponseStatus.ERROR.getMessage()); }}

July 24, 2020 · 3 min · jiezi

关于springboot:使用第三方开源库JustAuth登录案例

分享一波第三方登录的案例案例文档

July 21, 2020 · 1 min · jiezi

关于springboot:SpringBoot2-整合FreeMarker模板完成页面静态化处理

本文源码:GitHub·点这里 || GitEE·点这里 一、页面动态化1、动动态页面动态页面 即动态网页,指曾经装载好内容HTML页面,无需通过申请服务器数据和编译过程,间接加载到客户浏览器上显示进去。艰深的说就是生成独立的HTML页面,且不与服务器进行数据交互。 优缺点形容: 动态网页的内容稳固,页面加载速度极快;不与服务器交互,晋升安全性;动态网页的交互性差,数据实时性很低;维度老本高,生成很多HTML页面;动静页面 指跟动态网页绝对的一种网页编程技术,页面的内容须要申请服务器获取,在不思考缓存的状况下,服务接口的数据变动,页面加载的内容也会实时变动,显示的内容却是随着数据库操作的后果而动静扭转的。 优缺点形容: 动静网页的实时获取数据,提早性低;依赖数据库交互,页面保护老本很低;与数据库实时交互,安全控制的老本高;页面加载速度非常依赖数据库和服务的性能;动静页面和动态页面有很强的相对性,比照之下也比拟好了解。 2、利用场景动静页面动态化解决的利用场景十分多,例如: 大型网站的头部和底部,动态化之后对立加载;媒体网站,内容通过渲染,间接转为HTML网页;高并发下,CDN边缘节点代理的动态网页;电商网站中,简单的产品详情页解决;动态化技术的基本:提醒服务的响应速度,或者说使响应节点提前,如个别的流程,页面(客户端)申请服务,服务解决,响应数据,页面装载,一系列流程走下来不仅简单,而且耗时,如果基于动态化技术解决之后,间接加载动态页面,好了申请完结。 二、流程剖析动态页面转换是一个绝对简单的过程,其中外围流程如下: 开发一个页面模板,即动态网页款式;提供接口,给页面模板获取数据;页面模板中编写数据接口返参的解析流程;基于解析引擎,把数据和页面模板合并;页面模板内容加载实现后转换为HTML动态页面;HTML动态页面上传到文件服务器;客户端(Client)获取动态页面的url加载显示;主流程大抵如上,如果数据接口响应参数有变,则须要从新生成动态页,所以在数据的加载实时性下面会低很多。 三、代码实现案例1、根底依赖FreeMarker是一款模板引擎:即一种基于模板和要扭转的数据,并用来生成输入文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId></dependency>2、页面模板这里既应用FreeMarker开发的模板款式。 <html><head> <title>PageStatic</title></head><body>主题:${myTitle}<br/><#assign text="{'auth':'cicada','date':'2020-07-16'}" /><#assign data=text?eval />作者:${data.auth} 日期:${data.date}<br/><table class="table table-striped table-hover table-bordered" id="editable-sample"> <thead> <tr> <th>规格形容</th> <th>产品详情</th> </tr> </thead> <tbody> <#list tableList as info> <tr class=""> <td>${info.desc}</td> <td><img src="${info.imgUrl}" height="80" width="80"></td> </tr> </#list> </tbody></table><br/><#list imgList as imgIF> <img src="${imgIF}" height="300" width="500"></#list></body></html>FreeMarker的语法和原有的HTML语法基本一致,然而具备一套本人的数据处理标签,用起来不算简单。 3、解析过程通过解析,把页面模板和数据接口的数据合并到一起即可。 @Servicepublic class PageServiceImpl implements PageService { private static final Logger LOGGER = LoggerFactory.getLogger(PageServiceImpl.class) ; private static final String PATH = "/templates/" ; @Override public void ftlToHtml() throws Exception { // 创立配置类 Configuration configuration = new Configuration(Configuration.getVersion()); // 设置模板门路 String classpath = this.getClass().getResource("/").getPath(); configuration.setDirectoryForTemplateLoading(new File(classpath + PATH)); // 加载模板 Template template = configuration.getTemplate("my-page.ftl"); // 数据模型 Map<String, Object> map = new HashMap<>(); map.put("myTitle", "页面动态化(PageStatic)"); map.put("tableList",getList()) ; map.put("imgList",getImgList()) ; // 动态化页面内容 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map); LOGGER.info("content:{}",content); InputStream inputStream = IOUtils.toInputStream(content,"UTF-8"); // 输入文件 FileOutputStream fileOutputStream = new FileOutputStream(new File("F:/page/newPage.html")); IOUtils.copy(inputStream, fileOutputStream); // 敞开流 inputStream.close(); fileOutputStream.close(); } private List<TableInfo> getList (){ List<TableInfo> tableInfoList = new ArrayList<>() ; tableInfoList.add(new TableInfo(Constant.desc1, Constant.img01)); tableInfoList.add(new TableInfo(Constant.desc2,Constant.img02)); return tableInfoList ; } private List<String> getImgList (){ List<String> imgList = new ArrayList<>() ; imgList.add(Constant.img02) ; imgList.add(Constant.img02) ; return imgList ; }}生成后的HTML页面间接应用浏览器关上即可,不再须要依赖任何数据接口服务。 ...

July 20, 2020 · 1 min · jiezi

关于springboot:springboot过滤器的实现方式1

1.自定义过滤器实现接口HandlerInterceptorpackage com.huacheng.config;import org.springframework.lang.Nullable;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Componentpublic class TimeInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(">>>>>>>>>>>preHandle执行了<<<<<<<<<<<<<<<<<<"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { System.out.println(">>>>>>>>>>>postHandle执行了<<<<<<<<<<<<<<<<<<"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { System.out.println(">>>>>>>>>>>afterCompletion执行了<<<<<<<<<<<<<<<<<<"); }}2.定义一个配置类,把这个自定义的过滤器注册进去package com.huacheng.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class WebConfig extends WebMvcConfigurerAdapter { @Autowired private TimeInterceptor timeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(timeInterceptor); }}3.写一个控制器测试package com.huacheng.controller;import com.huacheng.domain.User;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class UserController { @PostMapping("/user/getUser") public String getUser(User user) { System.out.println(user); return "hello"; }}4.应用postman工具测试控制台打印如下 ...

July 20, 2020 · 1 min · jiezi

关于springboot:springboot启动流程

springboot系列之启动流程Springboot简介springboot封装了Spring组件,基于约定优于配置。晋升了开发效率,本文次要解说springboot框架的启动过程。 启动流程剖析1、首先,咱们看一下启动类SpringApplication,它是位于org.springframework.boot包上面的。我的项目启动类源码 @SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}这里用到了SpringBootApplication注解,而后在main办法中启动boot利用。 2、咱们接下来看看SpringBootApplication注解的源码 @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class) Class<?>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ @AliasFor(annotation = EnableAutoConfiguration.class) String[] excludeName() default {}; /** * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses} * for a type-safe alternative to String-based package names. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; /** * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to * scan for annotated components. The package of each class specified will be scanned. * <p> * Consider creating a special no-op marker class or interface in each package that * serves no purpose other than being referenced by this attribute. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {};}它是位于org.springframework.boot.autoconfigure包上面的。咱们能够看到它依赖了几个重要的注解SpringBootConfiguration、EnableAutoConfiguration、ComponentScan这三个注解。其中EnableAutoConfiguration就是springboot主动配置用到的类,在接下来咱们将会重点介绍。 ...

July 19, 2020 · 10 min · jiezi

关于springboot:Mybatisplus实现主键自增和自动注入时间

mybatis-plus依赖导入<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency>倡议应用3.3.0后的版本。导入mybatis-plus就不必导入mybatis了,抵触! 连贯数据库spring.datasource.username=rootspring.datasource.password=19981204spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drivermybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl//配置默认日志设置主键自增@Data@AllArgsConstructor@NoArgsConstructorpublic class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; }应用注解 @TableId(type=IdType.AUTO),同时将数据库中的id字段设置为自增即可。 编写配置类来进行主动注入工夫(继承元数据类并重写它的insertFill和updateFill办法)应用注解@TableFiled(fill=FieldFill.INSERT)@Data@AllArgsConstructor@NoArgsConstructorpublic class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime;}package com.ls.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.time.LocalDateTime;/** * @author dell */@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now()); this.strictUpdateFill(metaObject,"updateTime",LocalDateTime.class,LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject,"updateTime",LocalDateTime.class,LocalDateTime.now()); }}

July 18, 2020 · 1 min · jiezi

关于springboot:Spring-Boot-2x-快速集成Kafka

1 KafkaKafka是一个开源分布式的流解决平台,一种高吞吐量的分布式公布订阅音讯零碎,它能够解决消费者在网站中的所有动作流数据。Kafka由Scala和Java编写,2012年成为Apache基金会下顶级我的项目。 2 Kafka长处低提早:Kafka反对低提早消息传递,速度极快,能达到200w写/秒高性能:Kafka对于音讯的散布,订阅都有高吞吐量。即便存储了TB级的信息,仍然可能保障稳固的性能可靠性:Kafka是分布式,分区,复制和容错的,保障零停机和零数据失落可扩大:用户能够从但个代理Broker开始作POC,而后缓缓扩大到由三个Broker组成的小型开发集群,接着扩大到数十个甚至数百个Broker集群进入生产阶段,能够在集群联机时进行扩大,而不会影响整个零碎的可用性多个生产者:无论这些客户应用雷同Topic还是多个Topic,Kafka都能无缝解决多个生产者,使得零碎能够非常容易聚合来自许多前端零碎的数据并使其保持一致多个消费者:Kafka具备多个消费者设计,能够读取任何但个音讯流而不会互相烦扰。多个Kafka消费者能够组成一个生产组进行操作并共享音讯流,从而确保每一条音讯只被整个生产组解决一次基于磁盘的保留:Kafka应用分布式提交日志,音讯可能疾速长久化到磁盘上。音讯长久化意味着如果消费者落后,无论是因为处理速度迟缓还是忽然的音讯涌入都不会有失落数据的危险,也意味着消费者能够被进行。音讯将保留在Kafka中,容许消费者重新启动并且从中断处获取解决信息而不会失落数据3 Kafka相干术语Broker:Kafka集群蕴含一个或多个服务器,这种服务器称为BrokerTopic:每条公布到Kafka的音讯都有一个类别,这个类别称为Topic。物理上不同Topic的音讯离开存储,逻辑上Topic的音讯尽管保留在一个或多个Broker上,但用户只需指定音讯的Topic即可生产或生产数据而不用关怀数据寄存于何处Partition:每个Topic蕴含一个或多个PartitionProducer:生产者,负责公布音讯到BrokerConsumer:消费者,向Broker读取音讯的客户端Consumer Group:每个Consumer属于一个特定的Consumer Group,能够为每个Consumer指定Group Name,否则属于默认Group4 入手干活4.1 环境Spring Boot 2.3.1IDEA 2020.1.1OpenJDK 11.0.7Kafka 2.5.0Kotlin 1.3.724.2 下载Kafka官网戳这里。下载并解压(留神须要Kafka与Spring Boot版本对应,能够参考这里): tar -xvf kafka_2.12-2.5.0.tgzcd kafka_2.12-2.5.0接着启动ZooKeeper与Kafka: bin/zookeeper-server-start.sh -daemon config/zookeeper.propertiesbin/kafka-server-start.sh config/server.propertiesKafka须要用到ZooKeeper,须要在启动Kafka之前启动ZooKeeper(ZooKeeper是一个开源的分布式应用程序协调服务,是Hadoop的组件,次要用于解决分布式应用中的一些数据管理问题)。Kafka默认应用9092端口,部署在服务器上须要留神防火墙以及平安组的解决。 4.3 新建工程思考到Spring Boot在2.3.0M1中(截至本文写作日期2020.07.14Spring Boot已更新到2.4.0M1)首次采纳Gradle而不是Maven来构建我的项目,换句话说日后Spring Boot的构建工具将从Maven迁徙到Gradle,Spring Boot团队给出的次要起因是能够缩小我的项目构建所破费的工夫,详情能够戳这里瞧瞧。另外因为另一个基于JVM的语言Kotlin的日渐崛起,后端开始逐步有人采纳Kotlin(只管不多,不过语法糖真的香,JetBrains家的语言配合IDE,爽得飞起),因而本示例我的项目将采纳两种形式搭建: Java+MavenKotlin+Gradle抉择的依赖如下(当然您喜爱的话能够在pom.xml或者build.gradle.kts外面加,对于Kotlin不须要Lombok): 4.4 我的项目构造Java版:Kotlin版: serialize:序列化/反序列化实体类Constant.java/Constant.kt:常量类Consumer.java/Consumer.kt:消费者类Entity.java/Entity.kt:实体类Producer.java/Product.kt:生产者类TestApplicationTests:测试类4.5 常量类蕴含Topic与GroupId,Java版: public class Constants { public static final String TOPIC = "TestTopic"; public static final String GROUP_ID = "TestGroupId";}Kotlin版: object Constants{ const val TOPIC = "TestTopic" const val GROUP_ID = "TestGroupId"}4.6 实体类@AllArgsConstructor@NoArgsConstructor@Data@Builderpublic class Entity { private long id; private String name; private int num;}说一下Lombok的几个注解: ...

July 17, 2020 · 3 min · jiezi

SpringBootMongoDB-实现图片存取

最近要实现一个公布博客性能,波及到博文中图片的保留与拜访了,在博文中图片对应:![图片形容](图片url)。由用户上传图片,咱们将其保留在 mongodb 数据库中,返回图片的 url 即可显示图片了。在这里把根本实现步骤整顿了一下记录下来增加 MongoDB 依赖并配置<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>spring: data: mongodb: uri: mongodb://192.168.56.101:27017/sysblog建设图片实体import org.bson.types.Binary;@Documentpublic class UploadFile { @Id private String id; private String name; // 文件名 private Date createdTime; // 上传工夫 private Binary content; // 文件内容 private String contentType; // 文件类型 private long size; // 文件大小 // getter/setter }此处 id 的类型要设置为 String ,MongoDB 会主动调配 id ,设置为数值型会报错。BSON 是一个二进制序列化格局,在MongoDB外面被用来做文档存储和近程程序调用,咱们应用 org.bson.types.Binary 类来封装文件内容。new Binary(byte[] byte)上传图片此处仅演示性能,便不分层等操作。 上传图片后,保留至 mongodb 数据库,并返回图片的拜访 url@Autowiredprivate MongoTemplate mongoTemplate;@PostMapping("/file/uploadImage")@ResponseBodypublic String uploadImage(@RequestParam(value = "image") MultipartFile file){ if(file.isEmpty()) return JSONResult.build(200, "请抉择一张图片", null); // 返回的 JSON 对象,这品种可本人封装 JSONResult jsonResult = null; String fileName = file.getOriginalFilename(); try { UploadFile uploadFile = new UploadFile(); uploadFile.setName(fileName); uploadFile.setCreatedTime(new Date()); uploadFile.setContent(new Binary(file.getBytes())); uploadFile.setContentType(file.getContentType()); uploadFile.setSize(file.getSize()); UploadFile savedFile = mongoTemplate.save(uploadFile); String url = "http://localhost:8080/file/image/"+ savedFile.getId(); jsonResult = JSONResult.build(200, "图片上传胜利", url); } catch (IOException e) { e.printStackTrace(); jsonResult = JSONResult.build(500, "图片上传失败", null); } return jsonResult;}MongoTemplate:操作 MongoDB 的类,例如增删改查等。你也能够创立一个 repository 层接口继承 MongoRepository,相似于 JPA 的操作。 ...

July 16, 2020 · 1 min · jiezi

springboot的自动配置原理

@SpringBootApplication注解就相当于三个注解@ComponentScan :通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从申明这个注解的类所在的包开始,扫描包及子包 @SpringBootConfiguration:组件配置类 @EnableAutoConfiguration开启主动配置性能

July 15, 2020 · 1 min · jiezi

GloryAdminspringbootspring-bootvueadmintemplate后台

Glory-AdminGloryAdmin是一个基于springboot2.1.9.RELEASE 和vue-admin-template搭建的后盾框架; GloryAdmin应用基于角色的权限治理。角色树是一个以“系统管理员”为根节点的树,权限树是由多个子权限树组成。“系统管理员”领有所有权限;非系统管理员角色能够查看以后角色和直属上级角色的信息,但只能增删改直属上级的角色的信息(直属上级:A是B的直属上级,则A必须为B的孩子节点)。 Glory-Admin 技术阐明演示零碎架构我的项目启动 数据库装置我的项目启动数据库 为什么要数据拆分?什么是分库分表?什么是分布式数据库?数据库的版本控制数据库缓存层cacheDao分库分表数据分片的拆分形式又分为垂直分片和程度分片罕用分片算法后端 权限设计我的项目构造Maven应用BOM治理日志记录用户操作日志前端技术阐明我的项目技术后端我的项目springboot前端我的项目Element UI & Vue.js数据库MySQL缓存Redis演示 零碎架构 我的项目启动数据库装置本我的项目应用mysql数据库,能够应用数据库脚本创立2个数据库 multi_module_db multi_module_db_01 我的项目启动后盾启动,应用28081端口 前端启动,应用9523端口 关上浏览器拜访 http://localhost:9523 admin a123456 数据库为什么要数据拆分?什么是分库分表?什么是分布式数据库?分库分表或者 sharding 的实质是摩尔定律的生效,将数据集中存储至繁多数据节点的解决方案,在性能、可用性和运维老本这三方面曾经难于满足互联网的海量数据场景。 单数据库不能撑持现有的业务,因而呈现了分库分表,应用多个数据库进行数据存储。分库分表简略了解就是一个篮子外面装的货色无限,影响了查找效率和容量,把篮子外面的货色分成N份,装到不同的篮子外面。从而突破容量限度,进步查问效率。 而后咱们说一下分布式数据库,国内比拟风行的有腾讯的TDSQL、阿里的OceanBase,PolarDB、华为的GaussDB等。基本上都是自主研发,强统一高可用、寰球部署架构、分布式有限程度扩大、高性能,千亿条记录、数百TB数据上的跨行跨表事务(为祖国点赞)。分布式数据库暗藏了数据库分库分表的策略,智能的进行数据的分库分表,应用起来就像操作一个数据库一样。 Flyway数据库的版本控制 数据库缓存层cacheDao因为内存操作和磁盘操作基本不是一个量级的,所以在大的我的项目中都须要对 磁盘型的数据库 做 内存型的缓冲层,将磁盘数据缓存到内存中。数据缓存层用于缓存整个数据层的数据,减速站点访问速度。本我的项目应用 AOP技术、Redis内存数据库 做数据缓存层。具体请自行查看代码 com/spring/common/aop/CacheDaoAspect.java 分库分表本我的项目应用sharding JDBC解决数据库的分库分表。依据业务场景,自行拆分数据。 通常我的项目都只有一个数据库,国内用的比拟多的是阿里云的druid做数据库的连接池。本我的项目应用mysql,druid,sharding JDBC。数据分库分片的原理,在程序外面保护多个数据库连接池,每个数据库连接池对应一个数据库。分库分表应用基于 XA 协定的两阶段事务解决。配置门路com.spring.common.config.shardingJDBC 数据分片的拆分形式又分为垂直分片和程度分片垂直拆分:依照业务拆分的形式称为垂直分片,又称为纵向拆分。依照业务将表散布到不同的数据库中,从而将压力扩散至不同的数据库。 程度拆分:不关怀业务逻辑分类,而是通过某张表的某个字段(或某几个字段),依据某种规定将数据扩散至多个库或表中。这里的规定,波及到的算法,咱们称为分片算法。 罕用分片算法(以下内容取自shardingJDBC文档) 准确分片算法对应 PreciseShardingAlgorithm,用于解决应用繁多键作为分片键的 = 与 IN 进行分片的场景。须要配合 StandardShardingStrategy 应用。 范畴分片算法对应 RangeShardingAlgorithm,用于解决应用繁多键作为分片键的 BETWEEN AND、>、<、>=、<=进行分片的场景。须要配合 StandardShardingStrategy 应用。 复合分片算法对应 ComplexKeysShardingAlgorithm,用于解决应用多键作为分片键进行分片的场景,蕴含多个分片键的逻辑较简单,须要利用开发者自行处理其中的复杂度。须要配合 ComplexShardingStrategy 应用。 ...

July 15, 2020 · 1 min · jiezi

springboot-设置默认参数SpringbootsetDefaultPropertiesmap不生效解决

咱们都晓得springboot 因为内置tomcat(中间件)间接用启动类就能够启动了。而且咱们有时想代码给程序设置一些默认参数,所以应用办法Springboot.setDefaultProperties(map) SpringApplication application = new SpringApplication(startClass);//Map<String, Object> params = new HashMap<>();params.put("lai.ws.test","test");application.setDefaultProperties(params);ApplicationContext context = application.run(startClass,args);于是启动后发现 lai.ws.test 竟然是null,也就是参数设置不胜利,百思不得其解。为此还断点进入SpringApplication 的源码里。最初发现以下源码 /** * Static helper that can be used to run a {@link SpringApplication} from the * specified sources using default settings and user supplied arguments. * @param primarySources the primary sources to load * @param args the application arguments (usually passed from a Java main method) * @return the running {@link ApplicationContext} */ public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); }各位,发现了没,又new 了一个SpringApplication。到此,问题答案找到了。如果启动类要设置默认参数,不必应用以下办法去启动 ...

July 15, 2020 · 1 min · jiezi

springboot2整合mybatisplus3踩到的坑

前言最近在进行我的项目重构,在架构师的倡议下,就把我的项目中mybatis切换成mybatis-plus。因为mybatis-plus在mybatis的根底上只做加强不做扭转,因而切换的老本很低,就只需改jar和配置内容,原先的代码无需改变。 因为mybatis-plus对mybatis的敌对反对,咱们花了一点工夫就把mybatis改成mybatis-plus,那革新成不胜利,先启动一下看不就晓得了。然而一启动就翻车了,报了如下的谬误 com.baomidou.mybatisplus.core.MybatisConfiguration.getLanguageDriver(Ljava/lang/Class;)Lorg/apache/ibatis/scripting/LanguageDriver;残缺的异样信息如下图 排查思路从打印的异样信息,咱们晓得是不存在getLanguageDriver()这个办法。跟进源码会发现getLanguageDriver这个办法可能是由 com.baomidou.mybatisplus.core.MybatisConfiguration或者MybatisConfiguration的父类 org.apache.ibatis.session.Configuration提供。由异样信息咱们能够猜想如果我的项目要启动胜利,就须要getLanguageDriver这个办法,而我的项目目前援用的MybatisConfiguration及其Configuration都有力提供,由此咱们能够推断咱们我的项目引入冒牌的MybatisConfiguration或者Configuration。更进一步的推断咱们我的项目中应该存在多个MybatisConfiguration或者Configuration。用人话来说,就是咱们我的项目存在类抵触,更直白点就是jar抵触 验证过程1、我的项目中存在多个MybatisConfiguration?按住快捷键Ctrl+Shift+R很遗憾事件不是咱们想的那样,MybatisConfiguration只有一个 2、我的项目中存在多个Configuration?按住快捷键Ctrl+Shift+R 果然存在2个Configuration。 3、验证包抵触利用maven-helper插件查看jar抵触 很显著存在mybatis包抵触,而且咱们我的项目引入的3.4.4版本的mybatis,而mybatis-plus须要引入的是3.5.3版本的mybatis 解决思路借助maven-helper插件,咱们能够看出我的项目是因为包传递依赖间接引入3.4.4版本的mybatis。因而咱们把有援用3.4.4版本mybatis的我的项目升级成引入mybatis 3.5.3版本就行 总结本文呈现的坑挺常见的,利用搜索引擎应该都能够找到答案。写这篇文章除了介绍如何解决这个坑,次要还是想介绍一种排查问题的思路,即假如验证法。因为并不是每次都能够从搜索引擎上找到答案,此时咱们就能够依据已知信息去一步步论证推断。最初如果对maven抵触解决感兴趣的敌人,能够查看下我之前写的文章maven依赖抵触以及解决办法

July 14, 2020 · 1 min · jiezi

Spring-Boot-230正式发布优雅停机配置文件位置通配符新特性一览

当大潮退去,才晓得谁在裸泳。。关注公众号【BAT的乌托邦】开启专栏式学习,回绝浅尝辄止。本文 https://www.yourbatman.cn 已收录,外面一并有Spring技术栈、MyBatis、中间件等小而美的专栏供以学习哦。 前言各位小伙伴大家好,我是A哥。北京工夫2020-05-15,Spring Boot 2.3.0版本正式公布了,次版本号的降级,个别会有些新个性进去。作为Java Coder的咱们有必要一览它的新new Feature,keep下技术节奏嘛。 A哥“第二工夫”晓得了这个音讯,而后在本人本机(请留神:非生产环境)体验了一把,而后再联合Spring Boot官网的Release Notes,在这里给你絮叨絮叨。 对于版本号Spring Boot代码库的版本好采纳“国内通用”(我本人yy的)的命名形式:主版本号.次版本号.订正号,所以通过版本号就能感触到它的变动到底大不大,你降级时是否须要倍加留神等等。那么此处我就对这种命名形式版本号的各段进行科普一波: 主版本号:齐全不兼容。产品定位变动、外围API大规模不兼容(比方包名变了)、架构形式降级不能向下兼容...... 举例:Configuration1.x -> 2.x;Zuul1.x -> 2.x;Spring Boot1.x -> 2.x;Netty4.x -> 5.x次版本号:绝对兼容。个别是减少新特新,删除掉废除的API,批改某些API不兼容。总的来说是影响比拟小,在可控范畴内的,但降级时不可漫不经心,必须做后期调研订正号:100%兼容。个别是修复bug、新增无伤大雅的一些个性等,个别想升就升这次Spring Boot降级到2.3.0版本,属于次版本号的降级,因而会带有些新个性,还是值得一看的。 注释Spring Boot v2.2仍然是沉闷的保护的版本,Spring Boot遵循的是Pivotal OSS反对策略,从公布日期起反对次要版本3年。然而呢,一般来说在次要/主要版本公布时,将会对上个次要版本至多提供12个月的反对(即便超过了3年),以解决要害的bug或者平安问题。 对于其它版本的保护沉闷状态和曾经EOL的日期,做出如下阐明: 2.2.x:反对的版本。2019.10公布,是当初的沉闷的骨干2.1.x:反对的版本。2018.10公布,会反对到2020.10月底2.0.x:生命已终止的版本。2018.3公布,2019.4.3进行保护1.5.x:生命已终止的版本。2017.1公布,是最初一个1.x分支,2019.8.1进行保护从官网页面也能够看出,只有反对的版本才会被列出来,对使用者是有肯定的疏导作用的: 简略回顾2.2版本的新个性很显著,Spring Boot2.2版本不是本文关怀的重点,但为了起到连接作用,本处把它的外围新个性列一下: Spring Framework 5.2:重大降级,能够看到它为Cloud Native的致力JUnit 5:从此版本开始,spring-boot-starter-test默认应用JUnit 5作为单元测试框架反对Java13性能晋升:体现在对所有的主动配置类改为了@Configuration的Lite模式,晋升性能。新增@ConfigurationPropertiesScan注解,主动扫描@ConfigurationProperties配置类反对RSocket上面咱们来理解下本次降级(2.3.0版本)的新个性,分为次要新个性和其它新个性离开论述。 次要新个性优雅停机这个新个性深入人心,是开发者、运维的福音啊。据我理解,很多中小型公司/团队都是应用kill -9(当然有些比拟“温顺”的团队也用kill -2)来停服的,这样暴力“停机”很容易造成业务逻辑执行失败,导致在一些业务场景下呈现数据不统一景象。尽管咱们能够通过一些伎俩(自研)来防止这个问题,但并不是每个公司/团队都去做了。这不Spring Boot2.3.0版本就内置了这个性能:优雅停机。 小常识:kill -2相似于你的Ctrl + C,会触发shutDownHook事件(从而敞开Spring容器);kill -9就没啥好说的,杀杀杀SB所有四个嵌入式web服务器(Jetty、Reactor Netty、Tomcat和Undertow)以及响应性和基于servlet的web利用都反对优雅的敞开。在敞开时,web服务器将不再容许新的申请,并将期待实现的申请给个宽限期让它实现。当然这个宽限期是能够设置的:能够应用spring.lifecycle.timeout-per-shutdown-phase=xxx来配置,默认值是30s。 留神,留神,留神:默认状况下,优雅关机并没有开启(还是立刻关机),你仅需增加server.shutdown=graceful配置即可开启优雅关机(取值参见2.3.0新增的Shutdown枚举类,默认值参见AbstractConfigurableWebServerFactory.shutdown属性值)。 配置属性的调整这个版本中,一些配置属性已被重命名或弃用(这会导致不向下兼容,须要特地引起留神),须要你做出调整。 那么如何晓得我当初用的哪些属性存在不兼容状况呢???官网给了一个很好的解决方案,这里我用个应用示例教你能够这么解决: 现状:在Spring Boot2.2.x环境中你有很多配置,痛点是不晓得哪些配置须要配替换成2.3.x中新的。此时你能够在工程下退出这个jar: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope></dependency>而后降级你的Spring Boot版本号为2.3.0,重新启动工程。本处以你配置文件里的spring.http.encoding.enabled=true为例,因为应用了SB的最新版本,因而能够在控制台看到如下日志输入: Property source 'applicationConfig: [classpath:/application.properties]': Key: spring.http.encoding.enabled Line: 3 Replacement: server.servlet.encoding.enabled日志说够明确了吧。有了这个好帮手,妈妈就不必再放心辣么多的配置项须要本人一个个去核查喽,依照批示一个个的批改即可。 ...

July 13, 2020 · 1 min · jiezi

SpringBoot使用拦截器打印日志

@Configurationpublic class WebMvcConfigurer extends WebMvcConfigurerAdapter { private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptorAdapter() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String userName = JWTUtil.getUsername(request.getHeader("X-Token")); String userId = JWTUtil.getUserId(request.getHeader("X-Token")); JSONObject json = new JSONObject(); json.put("userId", userId); json.put("userName", userName); json.put("userIp", request.getRemoteAddr()); json.put("requestInterface:", request.getRequestURI()); json.put("param",request.getParameterMap());// logger.debug("useId:{},userName:{},申请接口:{},申请IP:{},申请参数:{}",userId,userName,request.getRequestURI()// , request.getRemoteAddr(), JSON.toJSONString(request.getParameterMap())); logger.info(json.toString()); return true; } }); }}

July 13, 2020 · 1 min · jiezi

基于TKMyBatis和Vue的代码生成器

后端可生成Controller Serivce Model Mapper Mapper.xml前端可生成Vue对应页面https://github.com/WillLiaowh...

July 13, 2020 · 1 min · jiezi

如何正确控制springboot中bean的加载顺序总结

1.为什么须要管制加载程序springboot听从约定大于配置的准则,极大水平的解决了配置繁琐的问题。在此基础上,又提供了spi机制,用spring.factories能够实现一个小组件的主动拆卸性能。 在个别业务场景,可能你不大关怀一个bean是如何被注册进spring容器的。只须要把须要注册进容器的bean申明为@Component即可,spring会主动扫描到这个Bean实现初始化并加载到spring上下文容器。 而当你在我的项目启动时须要提前做一个业务的初始化工作时,或者你正在开发某个中间件须要实现主动拆卸时。你会申明本人的Configuration类,然而可能你面对的是好几个有相互依赖的Bean。如果不加以控制,这时候可能会报找不到依赖的谬误。 然而你明明曾经把相干的Bean都注册进spring上下文了呀。这时候你须要通过一些伎俩来管制springboot中的bean加载程序。 2.几个误区在正式说如何管制加载程序之前,先说2个误区。 在标注了@Configuration的类中,写在后面的@Bean肯定会被先注册 这个不存在的,spring在以前xml的时代,也不存在写在后面肯定会被先加载的逻辑。因为xml不是渐进的加载,而是全副parse好,再进行依赖剖析和注册。到了springboot中,只是省去了xml被parse成spring外部对象的这一过程,然而加载形式并没有大的扭转。 利用@Order这个标注能进行加载程序的管制 严格的说,不是所有的Bean都能够通过@Order这个标注进行程序的管制。你把@Order这个标注加在一般的办法上或者类上一点鸟用都没有。 那@Order能管制哪些bean的加载程序呢,咱们先看看官网的解释: {@code @Order} defines the sort order for an annotated component. Since Spring 4.0, annotation-based ordering is supported for many kinds of components in Spring, even for collection injection where the order values of the target components are taken into account (either from their target class or from their {@code @Bean} method). While such order values may influence priorities at injection points, please be aware that they do not influence singleton startup order which is an orthogonal concern determined by dependency relationships and {@code @DependsOn} declarations (influencing a runtime-determined dependency graph).最开始@Order注解用于切面的优先级指定;在 4.0 之后对它的性能进行了加强,反对汇合的注入时,指定汇合中 bean 的程序,并且特地指出了,它对于但实例的 bean 之间的程序,没有任何影响。 ...

July 13, 2020 · 2 min · jiezi

个人学习系列-Spring-Boot使用Cache缓存

后端开发总是要保证数据返回的速度越快越好,可是数据库查问就是那么个速度,通过优化SQL和数据库配置都不是最正当的办法。所以明天咱们来看一下缓存。Cache话说缓存,咱们总是第一工夫想到redis,可是最要害的是redis须要本人启动客户端,这就比拟麻烦了。咱们只是须要缓存简略的数据怎么办?springboot为咱们想到了这个问题,于是默认增加了缓存ConcurrentMapCacheManager。 1. 新建SpringBoot我的项目不再赘述,参考之前的文章即可 2. 批改pom.xml文件<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>这里咱们应用jpa。 3. 新建数据库表DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '姓名', `address` varchar(512) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '地址', `age` int NULL DEFAULT NULL COMMENT '年龄', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;4. 写代码啦4.1 新建实体类User/** * 实体类 * @author zhouzhaodong */@Entitypublic class User implements Serializable { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private int id; private String name; private String address; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", address='" + address + '\'' + ", age=" + age + '}'; }}4.2 新建数据库拜访层继承JpaRepository/** * 数据库拜访层 * @author zhouzhaodong */public interface UserRepository extends JpaRepository<User, Integer> { /** * 依据id更新 * * @param id * @param name * @param address * @param age */ @Modifying @Query(value = "update user u set u.name = :name, u.address = :address, u.age = :age where u.id = :id", nativeQuery = true) User updateById(@Param("id") Integer id, @Param("name") String name, @Param("address") String address, @Param("age") int age);}4.3 定义业务层类/** * Service * @author zhouzhaodong */@Servicepublic interface UserService { /** * 新增 * @param user * @return */ User insert(User user); /** * 删除 * @param id * @return */ void delete(int id); /** * 更新 * @param user * @return */ void update(User user); /** * 依据id查问 * @param id * @return */ Object findById(int id);}/** * 实现类 * @author zhouzhaodong */@Servicepublic class UserServiceImpl implements UserService { @Resource UserRepository userRepository; @Override @CachePut(value = "user", key = "#result.id") public User insert(User user) { return userRepository.save(user); } @Override @CacheEvict(value = "user", key = "#id") public void delete(int id) { userRepository.deleteById(id); } @Override @CachePut(value = "user", key = "#user.id") public User update(User user) { return userRepository.updateById(user.getId(), user.getName(), user.getAddress(), user.getAge()); } @Override @Cacheable(value = "user", key = "#id") public Object findById(int id) { return userRepository.findById(id); }}4.4 管制层/** * 管制层 * @author zhouzhaodong */@RestControllerpublic class UserController { @Resource UserService userService; @RequestMapping("/save") public User saveUser(User user){ return userService.insert(user); } @RequestMapping("/delete") public void deleteUser(int id){ userService.delete(id); } @RequestMapping("/update") public User updateUser(User user){ return userService.update(user); } @RequestMapping("/find") public Object findById(int id){ return userService.findById(id); }}4.5 启动类增加注解/** * 启动类 * @author zhouzhaodong */@SpringBootApplication@EnableCachingpublic class CacheApplication { public static void main(String[] args) { SpringApplication.run(CacheApplication.class, args); }}4.6 application配置文件server: port: 8989 # 端口号spring: datasource: url: jdbc:mysql://ip地址:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true username: 用户名 password: 明码 jpa: show-sql: true # 打印sql properties: hibernate: format_sql: true # 打印sql5. post测试首先新增数据,而后进行查问就会发现并不走数据库查问,控制台不打印sql,缓存胜利。 ...

July 13, 2020 · 3 min · jiezi

八-SpringBoot起飞之路整合Shiro详细教程MyBatisThymeleaf

趣味的敌人能够去理解一下前几篇,你的赞就是对我最大的反对,感激大家! (一) SpringBoot腾飞之路-HelloWorld (二) SpringBoot腾飞之路-入门原理剖析 (三) SpringBoot腾飞之路-YAML配置小结(入门必知必会) (四) SpringBoot腾飞之路-动态资源解决 (五) SpringBoot腾飞之路-Thymeleaf模板引擎 (六) SpringBoot腾飞之路-整合JdbcTemplate-Druid-MyBatis (七) SpringBoot腾飞之路-整合SpringSecurity 阐明: 这一篇的目标还是整合,也就是一个具体的实操体验,原理性的没波及到,我自身也没有深入研究过,就不献丑了SpringBoot 腾飞之路 系列文章的源码,均同步上传到 github 了,有须要的小伙伴,随便去 down https://github.com/ideal-20/S...满腹经纶,就会点肤浅的常识,大家权当一篇工具文来看啦,不喜勿愤哈 ~(一) 初识 Shiro(1) 引言权限以及平安问题,尽管并不是一个影响到程序、我的项目运行的必须条件,然而却是开发中的一项重要思考因素,例如某些资源咱们不想被拜访到或者咱们某些办法想要满足指定身份才能够拜访,咱们能够应用 AOP 或者过滤器来实现要求,然而实际上,如果代码波及的逻辑比拟多当前,代码是极其繁琐,冗余的,而有很多开发框架,例如 Spring Security,Shiro,曾经为咱们提供了这种性能,咱们只须要晓得如何正确配置以及应用它了 (2) 根本介绍官网:http://shiro.apache.org/ Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications. ...

July 13, 2020 · 9 min · jiezi

SpringBoot2-整合JTA组件多数据源事务管理

本文源码:GitHub·点这里 || GitEE·点这里 一、JTA组件简介1、JTA基本概念JTA即Java-Transaction-API,JTA容许应用程序执行分布式事务处理,即在两个或多个网络计算机资源上拜访并且更新数据。JDBC驱动程序对JTA的反对极大地加强了数据拜访能力。 XA协定是数据库层面的一套分布式事务管理的标准,JTA是XA协定在Java中的实现,多个数据库或是音讯厂商实现JTA接口,开发人员只须要调用SpringJTA接口即可实现JTA事务管理性能。 JTA事务比JDBC事务更弱小。一个JTA事务能够有多个参与者,而一个JDBC事务则被限定在一个繁多的数据库连贯。下列任一个Java平台的组件都能够参加到一个JTA事务中 2、分布式事务分布式事务(DistributedTransaction)包含事务管理器(TransactionManager)和一个或多个反对 XA 协定的资源管理器 ( Resource Manager )。 资源管理器是任意类型的长久化数据存储容器,例如在开发中罕用的关系型数据库:MySQL,Oracle等,消息中间件RocketMQ、RabbitMQ等。 事务管理器提供事务申明,事务资源管理,同步,事务上下文流传等性能,并且负责着所有事务参加单元者的互相通信的责任。JTA标准定义了事务管理器与其余事务参与者交互的接口,其余的事务参与者与事务管理器进行交互。 二、SpringBoot整合JTA我的项目整体结构图 1、外围依赖<!--SpringBoot外围依赖--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><!--JTA组件外围依赖--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency>2、环境配置这里jtaManager的配置,在日志输入中十分要害。 spring: jta: transaction-manager-id: jtaManager # 数据源配置 datasource: type: com.alibaba.druid.pool.DruidDataSource data01: driverClassName: com.mysql.jdbc.Driver dbUrl: jdbc:mysql://localhost:3306/data-one username: root password: 000000 data02: driverClassName: com.mysql.jdbc.Driver dbUrl: jdbc:mysql://localhost:3306/data-two username: root password: 0000003、外围容器这里两个数据库连贯的配置手法都是一样的,能够在源码中自行下载浏览。基本思路都是把数据源交给JTA组件来对立治理,不便事务的通信。 数据源参数 @Component@ConfigurationProperties(prefix = "spring.datasource.data01")public class DruidOneParam { private String dbUrl; private String username; private String password; private String driverClassName;}JTA组件配置 ...

July 12, 2020 · 2 min · jiezi

SpringBoot项目jar包运行

前言终于等来了假期,也终于等来了团队学习,考试周来的时候真的很慌乱,不只是因为考试,更是因为团队学习的中断,学习就应该一鼓作气,趁着精力旺盛,也趁着本人趣味在这,温习的时候就怕玩游戏,小游戏也不行,毕竟比起学习来,游戏要有很大的吸引力,对于团队学习来说,温习周就相当于劳动,一旦工夫过长,就容易被转移注意力,好在当初回到正规了。最近潘老师在Alice的我的项目上提交了一个这样的issue:而后来到研究生考试零碎看一下这个文件:有一说一,没看懂,然而我感兴趣的是jar包,之前在团队汇报时就据说过这个名词,然而没有接触过,也不晓得是啥,而后就试着打包和运行我的项目 打包首先在POM.XML文件中要有插件:spring-boot-maven-plugin <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>而后就是进入POM.XML文件所在的目录,而后执行语句: mvn clean package -Dmaven.test.skip=true最初会呈现BUILD SUCCESS 字样,阐明打包胜利,而后在target文件中会生成jar包由图标款式咱们能够晓得,所谓的jar包就是压缩包。当然也能够应用命令: mvn clean package应用该命令后会进行测试,胜利后打包文件。 运行我的项目想要把我的项目运行起来,只须要一句: java -jar alice-0.0.1-SNAPSHOT.jar (前面的jar包请依据本人系统生成的jar包名称填写) jar包JAR 文件的全称 Java Archive File(Java 档案文件),通常 JAR 文件是一种压缩格局,和 ZIP 格局兼容,与 ZIP格局不同的是它 蕴含了一个名为 META-INF/MANIFEST.MF的清单文件解压jar包看一下它的构造:(现场演示)MANIFEST.MF文件中有如下内容: Manifest-Version: 1.0Implementation-Title: aliceImplementation-Version: 0.0.1-SNAPSHOTBuilt-By: jinchengImplementation-Vendor-Id: com.yunzhiclubCreated-By: Apache Maven 3.6.0Build-Jdk: 1.8.0_172Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo ot-starter-parent/alice对于创建者和版本号等信息。 关上实体文件,发现外面有如下文件:结尾后缀均为.class .classJava字节码类文件(.class)是Java编译器编译Java源文件(.java)产生的“指标文件”。它是一种8位字节的二进制流文件, 各个数据项按程序严密的从前向后排列, 相邻的项之间没有间隙, 这样能够使得class文件十分紧凑, 体积笨重, 能够被JVM疾速的加载至内存, 并且占据较少的内存空间(不便于网络的传输)。用jd-gui反向解析一下.class文件:通过图标咱们能够晓得,正如下面说的,.class文件是二进制文件,变量和类型放在后面,办法放在前面咱们看一下College.class寄存的货色: javap -v College.class javap命令次要用于反编译java的class文件 查看.class文件寄存的二进制流信息并且理解他们的含意,请参考此博客:深刻了解JVM之Java字节码(.class)文件详解 ...

July 10, 2020 · 1 min · jiezi

一分钟实践数据库索引

前言后面咱们以及学习了如何利用sql语句进行循环增加数据,在增加了大量的数据之后咱们就能够学习与实际索引了!!高兴+1 常识+2 好上面咱们开始 创立数据循环测试表代码 create table test(location_id int ,location_name varchar(20));再编写存储过程,其中波及到循环的应用。咱们欲通过这个存储过程,来达到往表中插入数据的成果,这里插入一百万条Sql drop procedure if exists insert_while;delimiter //create procedure insert_while()begin declare i int default 1; while i<1000000 do insert into test values(i,concat('bookworm',i)); set i=i+1; end while; commit;end //delimiter ;运行以及破费工夫: mysql> call test_loop();call insert_while()OK工夫: 542.984s 5种索引以及创立办法增加主键索引: alter table table_name add primary key ( column ) 增加惟一索引: alter table table_name add unique ( column ) 一般索引: alter table table_nameadd index index_name( column ) ...

July 10, 2020 · 1 min · jiezi

优雅写代码系统bootmybatispagehelpermybatisplusdruid教你优雅写代码

[TOC] springboot 交融了很多插件。springboot相比spring来说有一下有点主动配置: 针对很多spring的应用程序,springboot提供了很多主动配置起步依赖: 通知springboot你须要什么,他就会引入须要的库命令行界面:springboot的可选个性Autuator: 监控springboot我的项目的运行状况spring根本搭建springboot的配置很简略。在pom中继承springboot的pom .而后依赖一下pom就能够继承所需的jar了<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version></parent><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope></dependency>出了jar外。咱们pom中配置一个插件就行了<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins></build>整合mybatis【详见feature/0002/spring-mybatis 分支】 之前咱们梳理过mybatis的运行机制及留神点。javaweb的开发时离不开spring的。一个残缺的框架是离不开spirng的。所以spring整合mybatis势在必行。咱们上面实现如何在spring下交融mybatis及其优良的一些插件搭建架构pom配置咱们在springboot我的项目的pom中持续增加咱们mybatis的jar就实现了第一步。一个是mybatis与spring的整合jar 。 开启springboot加载mybatis我的项目一个是spring的aopjar包。次要是实现mybatis的事务问题一个是mysql的jar包。这里次要看你本人的需要。如果你的我的项目中应用oracle那么久退出oracle的坐标就行了druid是治理数据的数据源<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version></dependency>mybatis配置下面的pom设置曾经筹备了mybatis开发阶段的根本jar。 有了上述的包就能够搭建mybatis . 失常咱们在咱们的springboot我的项目中配置一个bean配置的类 MybatisConfig设置数据源@Bean@ConfigurationProperties("spring.datasource")public DataSource primaryDataSource() { // 这里为了演示,临时写死 。 实际上是能够通过autoConfigure拆卸参数的 DruidDataSource dataSource = new DruidDataSource(); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://192.168.44.130:3306/others?useUnicode=true&amp;characterEncoding=utf8"); return dataSource;}在springboot中咱们只须要在办法上增加Bean注解,就相当于咱们在spring的xml中配置的bean标签。在java代码中咱们能够进行咱们业务解决。集体了解感觉更加的可控。 因为咱们应用的mysql。所以这里咱们简略的应用druid的数据源设置sqlsessionfactory@Beanpublic SqlSessionFactory primarySqlSessionFactory() { SqlSessionFactory factory = null; try { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(primaryDataSource()); sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-primary.xml")); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/com/github/zxhtom.**./*.xml")); factory = sqlSessionFactoryBean.getObject(); } catch (Exception e) { e.printStackTrace(); } return factory;}在mybatis中sqlsesson是咱们操作数据库最间接的java类。治理sqlsession就是下面的sqlsessionFactory 。 所以咱们配置它也是必须的。因为和spring整合。Mybatis的SqlsessionFactory交由给spring的SqlsessionfactoryBean治理。所以咱们先构建SqlSessionFactoryBean。而后配置必须的数据源、Configuration、mybatis的xml门路等等信息SqlSessionFactoryBean 设置出了spring的FactoryBean属性意外。最重要的是能够设置Mybatis的sqlsessionfactory的属性。下面咱们只是简略的设置了。前期能够依据架构的需要进行一直的欠缺。能够设置插件、缓存、别名、映射处理器、事务、环境等等所有mybatis的配置设置扫描@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactory(primarySqlSessionFactory()); //每张表对应的*.java,interface类型的Java文件 mapperScannerConfigurer.setBasePackage("com.github.zxhtom.**.mapper"); return mapperScannerConfigurer;}springboot 中咱们的mapper接口也是交由spring来扫描的。之前mybatis程序咱们是一个一个手动退出的。spring的个性能够间接扫描指定门路的所有java类。这里咱们就设置了一下mapper的门路。设置开启事务优良的架构没有事务是能应用的。咱们配置事务也是很简略的。在springboot中咱们举荐应用java代码来配置事务的。上面的配置咱们为了容易浏览。配置在TransactionConfig类中@Beanpublic DataSourceTransactionManager primaryTransactionManager() { return new DataSourceTransactionManager(dataSource);}首先是配置事务管理器。事务管理的是数据源。所以这里咱们须要将MybatisConfig中的DataSource加载进来。这里不多说而后配置咱们的告诉点@Beanpublic TransactionInterceptor txAdvice() { DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute(); txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute(); txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txAttr_REQUIRED_READONLY.setReadOnly(true); NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource(); source.addTransactionalMethod("add*", txAttr_REQUIRED); source.addTransactionalMethod("save*", txAttr_REQUIRED); source.addTransactionalMethod("delete*", txAttr_REQUIRED); source.addTransactionalMethod("update*", txAttr_REQUIRED); source.addTransactionalMethod("exec*", txAttr_REQUIRED); source.addTransactionalMethod("set*", txAttr_REQUIRED); source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY); return new TransactionInterceptor(primaryTransactionManager(), source);}最初咱们配置一下咱们的切面、切点@Beanpublic Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice());}@Beanpublic Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice());}最初阐明下。TransactionConfig这个类因为配置事务、拦挡所以咱们须要退出如下注解在雷伤@Configuration@Aspect@EnableTransactionManagement资源放行以上就是mybatis根本的一个配置了。然而这个时候还是不能应用的。因为咱们的mapper对应的xml是放在java目录下的。失常src下都是java。xml文件在maven编译时不放行的。咱们须要非凡解决下在pom的build下退出放行配置<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> <include>**/*.yaml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> <filtering>false</filtering> </resource></resources>退出如下配置后别忘记了clean一下在运行。避免缓存。clean之后看看target下文件 ...

July 10, 2020 · 3 min · jiezi

Spring-Boot读取配置文件的几种方式

Spring Boot获取文件总的来说有三种方式,分别是@Value注解,@ConfigurationProperties注解和Environment接口。这三种注解可以配合着@PropertySource来使用,@PropertySource主要是用来指定具体的配置文件。 @PropertySource解析@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Repeatable(PropertySources.class)public @interface PropertySource { String name() default ""; String[] value(); boolean ignoreResourceNotFound() default false; String encoding() default ""; Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;}value():指定配置文件encoding():指定编码,因为properties文件的编码默认是ios8859-1,读取出来是乱码factory():自定义解析文件类型,因为该注解默认只会加载properties文件,如果想要指定yml等其他格式的文件需要自定义实现。一、@Value注解读取文件新建两个配置文件config.properties和configs.properties,分别写入如下内容: zhbin.config.web-configs.name=Java旅途zhbin.config.web-configs.age=22zhbin.config.web-configs.name=Java旅途zhbin.config.web-configs.age=18新增一个类用来读取配置文件 @Configuration@PropertySource(value = {"classpath:config.properties"},encoding="gbk")public class GetProperties { @Value("${zhbin.config.web-configs.name}") private String name; @Value("${zhbin.config.web-configs.age}") private String age; public String getConfig() { return name+"-----"+age; }}如果想要读取yml文件,则我们需要重写DefaultPropertySourceFactory,让其加载yml文件,然后在注解 @PropertySource上自定factory。代码如下: public class YmlConfigFactory extends DefaultPropertySourceFactory { @Override public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { String sourceName = name != null ? name : resource.getResource().getFilename(); if (!resource.getResource().exists()) { return new PropertiesPropertySource(sourceName, new Properties()); } else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) { Properties propertiesFromYaml = loadYml(resource); return new PropertiesPropertySource(sourceName, propertiesFromYaml); } else { return super.createPropertySource(name, resource); } } private Properties loadYml(EncodedResource resource) throws IOException { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); factory.afterPropertiesSet(); return factory.getObject(); }}@PropertySource(value = {"classpath:config.properties"},encoding="gbk",factory = YmlConfigFactory.class)二、Environment读取文件配置文件我们继续用上面的两个,定义一个类去读取配置文件 ...

July 8, 2020 · 2 min · jiezi

CKEditor-5-SpringBoot实战四SpringBoot-实现文件上传

在本系列的文章中,我将介绍如何在Spring Boot Application中使用CKEditor编辑器。介绍的内容包括基本环境的搭建,文件上传,SpringData JPA数据持久化,CKEditor5的安装,CKEditor图片上传,CKEditor插入视频,获取/设置CKEditor内容等。 在本章节中,主要介绍的内容是在SpringBoot中实现图片上传功能,其中包括上传路径的设置,图片路径映射和上传业务代码的编写。 文件上传所谓的文件上传就是将客户端的资源通过网络传输到服务端,其本质就是IO流操作。服务端通过IO流读取客户端数据,然后对数据进行解析,获取目标文件数据后,将数据存储到服务端磁盘中。 引入依赖要实现文件上传,首先需要将所需要的依赖包导入到项目中。这里我们仅导入commons-fileupload和commons-io依赖包。通常,commons-fileupload依赖需要和commons-io一起搭配使用,其中封装了大量的用于操作文件上传的功能,可以帮助我们简化文件上传代码的编写。打开pom.xml配置文件,并加入如下的配置: <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version></dependency><dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version></dependency>存储路径上面我们提到,文件上传的本质就是通过IO流将客户端数据存储到服务端的磁盘上。因此,我们需要在服务端的磁盘上规划一个存储空间,用于存储客户端上传的文件。这里我将客户端上传的文件存储到当前项目的类路径下的images文件夹中。 首先,在com.ramostear.ckeditor.common包中创建一个Consts类,然后通过ClassPathResource类获得当前项目的类路径。代码如下: package com.ramostear.ckeditor.common;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import java.io.IOException;public class Consts { public static String FILE_STORAGE_ROOT = getRootPath(); private static String getRootPath(){ try { Resource resource = new ClassPathResource(""); return resource.getFile().getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } return null; }}在代码中,获取到的类路径赋值给了公有静态常量 FILE_STORAGE_ROOT,该常量将在图片路径映射和文件上传业务代码中被使用。 上传配置一般情况下,客户端的数据可以通过Form表单传递到服务端,但如果是图片等大文件数据,服务端将无法直接解析这些数据(如果是图片文件,也可以将图片通过Base64转码后,将获得的二进制文本传递到服务端),因此,我们需要配置一个专门用于解析客户端上传文件的解析器,另外,如果上传的是图片文件,通常需要在上传成功后显示这些图片,在SpringBoot中,客户端是无法直接去加载这些文件的,这就要求我们还得手动去映射图片地址。 下面,将介绍如何在SpringBoot中配置文件上传的相关参数。最简单的配置方式是配置类继承 WebMvcConfigurationSupport类,然后重写其中对应的方法。首先是文件解析器,这里我们实例化一个CommonsMultipartResolver来作为上传文件的解析器,然后设置其允许上传文件的大小和文件的字符编码,代码如下: @Beanpublic CommonsMultipartResolver multipartResolver(){ CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(600000000); resolver.setDefaultEncoding("UTF-8"); return resolver;}提示:在代码中,setMaxUploadSize()方法用于限制上传文件大小的最大值,单位为字节,如果你不想对上传文件做大小限制,可将值设置为-1,默认值也是-1。 ...

July 7, 2020 · 3 min · jiezi

CKEditor-5-SpringBoot实战三SpringData-JPA数据持久化

在本系列的文章中,我将介绍如何在Spring Boot Application中使用CKEditor编辑器。介绍的内容包括基本环境的搭建,文件上传,SpringData JPA数据持久化,CKEditor5的安装,CKEditor图片上传,CKEditor插入视频,获取/设置CKEditor内容等。 项目源码本系列文章的项目源码同步更新至码云 和 Github ,你可以任选其一下载源码到本地。项目地址如下: 码云:https://gitee.com/ramostear/CKEditor5-SpringBootGithub:https://github.com/ramostear/CKEditor5-SpringBoot你也可以通过Git命令行工具下载项目源码,命令如下(二者任选其一): git clone https://gitee.com/ramostear/CKEditor5-SpringBoot.gitgit clone https://github.com/ramostear/CKEditor5-SpringBoot.git接上篇内容,本篇的主要内容是引入MySQL数据库驱动依赖和SpringData JPA依赖,然后创建内容实体,并完成数据持久层(DAO)和业务逻辑层(Service)相关代码的设计和实现。 引入依赖前面的内容中我们分析过,需要将CKEditor5编辑的内容存储到数据库中(图片数据存储到磁盘)。本项目使用MySQL数据库来存储数据。数据的持久化过程选用SpringData JPA进行实现,除此之外,我们借用Alibaba Druid来管理数据库连接池。 在项目根目录下找到并打开pom.xml文件,然后向文件中添加如下的依赖: SpringData JPA <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>MySQL Driver <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> <scope>runtime</scope></dependency>Alibaba Druid <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.14</version></dependency>项目配置依赖包加载完成,我们需要对项目中的JPA和数据源进行配置。配置的内容包括数据库的类型,数据库方言,数据源类型,数据库驱动以及连接数据库所需要的用户名,密码和连接地址。详细配置如下图: 在“src/main/resources”目录下找到_application.properties_ 文件,并将该文件更名为_application.yml_ 并添加下列配置信息: spring: jpa: database: mysql show-sql: true hibernate: ddl-auto: update database-platform: org.hibernate.dialect.MySQL5Dialect properties: hibernate.format_sql: true datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver username: root password: root url: jdbc:mysql://localhost:3306/db_ckeditor_springboot?useUnicode=true&useSSL=false&characterEncoding=utf8如上图所示: ①:指定数据库类型为MySQL数据库 ②:在启动项目时,如果数据库表和对应的实体之间的映射不一致,则更新数据库表,并保留原有数据 ...

July 7, 2020 · 2 min · jiezi