初始SpringBoot
SpringBoot称为Spring的脚手架(脚手架就是盖房子的框架).
Spring是为了简化Java程序的开发诞生的, 而SpringBoot是为了简化Spring程序开发诞生的.所以称为Spring的框架.
这里有三种创建方式, 专业版idea中自带方式, 和 社区版安装插件后的方式. 第三种方式, 就是在官网下载项目的压缩包.然后解压到自己选择的位置, 再用idea打开即可.(其实三种方式大同小异, 知道一种也可以很快的熟悉另外两种方式)



为了不体现对待专业版特殊化, 我们先讲解社区版插件的方式
先选择New Project 进入到创建新项目的页面, 点击插件的模块
然后 选择自己对应的JDK 和 依赖源, 依赖源一般有默认值,可以不填写, 如果需要用国内稳定源, 可以在Custom中配置






同样先选择New Project 进入到创建页面, 然后选择Spring Initializr框
填写相关内容, 如果需要更改拉取的源地址, 可以在上面更改. 填写好以后就可以点击Next



我们观察后, 不难发现, 两种创建方式创建出来的项目是没有什么差别的, 所以以后我们使用哪种方式都是可以的.
首先访问官网地址: https://start.spring.io/
访问之后填写和更改具体内容, 选择要添加的依赖(内容和idea创建类似)

SpringBoot项目有两个主要的目录
具体细节如图:


启动类代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ShowSpringbootUltimateApplication {
public static void main(String[] args) {
SpringApplication.run(ShowSpringbootUltimateApplication.class, args);
}
}





代码如下:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/sayhello")
public String sayHi() {
return "Hello World!";
}
}

注意事项: 约定大于配置!!! 上述编写代码, 运行成功是因为. 我们遵守了 项目要求的目录格式, 如果我们将controller没有建在启动类的包下, 就会出现错误.(SpringBoot 没有将对象注入到容器中). 因为默认情况下, 启动类只会注入自己同级别的包下的内容.所以要记住 约定大于配置.要遵守约定好的目录格式.
整个项目中所有重要的数据都是在配置文件中配置的
可见配置文件还是很重要的.
一般有两种格式 .properties文件 和 .yml文件, 并且这两种格式的配置文件是可以共存的

属于老版本的配置文件, 是创建SpringBoot项目默认的配置文件
基本语法
读取配置文件

代码如下:
# .properties文件
server.port=8031
// .java文件
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
private String port;
@RequestMapping("/readport")
public String readPort() {
return "port: " + port;
}
@RequestMapping("/sayhello")
public String sayHi() {
return "Hello World!";
}
}
重启项目, 访问页面观察结果

以配置数据库为例, 可以观察出来很明显的缺点就是会有很多冗余信息

yml格式的配置文件就不会出现这样的冗余信息
基本语法: key: value
示例: key: value :和value中间必须有空格

使用yml连接数据库示例

代码如下:
# 演示yml配置数据库
spring:
datasource:
url: mysql://localhost:3306/fhs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=true
username: root
password: 123456

yml代码
# 字符串
string.value: Hello
# 布尔值,true或false
boolean.value: true
boolean.value1: false
# 整数
int.value: 10
int.value1: 0b1010_0111_0100_1010_1110 # 二进制
# 浮点数
float.value: 3.14159
float.value1: 314159e-5 # 科学计数法
# Null, ~代表null
null.value: ~

application.yml代码
string:
str1: Hello \n Spring Boot.
str2: 'Hello \n Spring Boot.'
str3: "Hello \n Spring Boot."
UserController.java代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${string.str1}")
private String str1;
@Value("${string.str2}")
private String str2;
@Value("${string.str3}")
private String str3;
//初始化调用
@PostConstruct
public void postConstruct() {
System.out.println("string.str1:" + str1);
System.out.println("string.str2:" + str2);
System.out.println("string.str3:" + str3);
}
}
补充: 关于@PostConstruct 注解
a. 类初始化时调用的方法
放在这里的原因是因为希望在项目启动时观察到方法输出, 并且这个注解又需要等待 属性注入, 否则无意义
b. 类初始化时调用的顺序
1. 构造方法 Constructor
2. @Autowired
3. @PostConstruct
配置: 首先在配置文件中配置对象, 有两种配置写法 普通写法和行内写法,两种同等效益

application.yml代码
# 配置对象
student:
id: 1
name: Java
age: 18
# 行内写法
student2: { id: 1,name: Java,age: 18 }
获取: 编写对象类, 获取配置信息并观察.
右键show_springboot_ultimate包选择New–>Java Class

在运行类同级目录下创建一个子包和一个对象类

编写对象类并获取配置内容. 这个时候就不能⽤ @Value 来读取配置中的对象了,此时要使⽤另⼀个注解 @ConfigurationProperties来读取

StudentComponent.java代码
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "student")
@Component
public class StudentComponent {
private int id;
private String name;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "StudentComponent{" +
"id=" + id +
", name='" + name + ''' +
", age=" + age +
'}';
}
}
编写代码, 并重启项目. 观察Student对象配置信息获取情况. 可以观察到,成功获取信息.

ReadYml.java代码
import com.example.show_springboot_ultimate.model.StudentComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class ReadYml {
@Autowired
private StudentComponent studentComponent;
@PostConstruct
public void postConstruct() {
System.out.println(studentComponent);
}
}
配置: 和配置对象类似, 有两种书写方式 普通写法和行内写法

application.yml代码
# 配置集合
dbtypes:
name:
- mysql
- sqlserver
- db2
# 行内写法
dbtypes2: { name: [ mysql,sqlserver,db2 ] }
获取: 同样编写有集合属性的类来观察, 先在model包下New一个类

创建拥有集合属性的类来接收获取的配置文件的信息

编写代码并获取配置信息. 集合的读取和对象⼀样,也是使用 @ConfigurationProperties 注解来读取的

ListConfig.java代码
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties("dbtypes")
@Data
public class ListConfig {
private List<String> name;
}
编写代码, 并重启项目. 观察集合配置信息获取情况. 可以观察到,成功获取信息.

ReadYmlList.java代码
import com.example.show_springboot_ultimate.model.ListConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class ReadYmlList {
@Autowired
private ListConfig listConfig;
@PostConstruct
public void postConstruct() {
System.out.println(listConfig.getName());
}
}


UserController.java代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
/**
* @author Echo
* @version 1.0
* date 2023/3/24 16:15
* name UserController
* @deprecated exercises:
* 类初始化调用顺序
* (1)构造方法Constructor
* (2)@Autowired
* (3)@PostConstruct
*/
@RestController
@RequestMapping("/user")
public class UserController {
//首先获取日志对象
//不要导错包了.
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
private static Logger logger = LoggerFactory.getLogger(UserController.class);
@Value("${server.port}")
private String port;
@Value("${string.str1}")
private String str1;
@Value("${string.str2}")
private String str2;
@Value("${string.str3}")
private String str3;
//初始化调用
@PostConstruct
public void postConstruct() {
logger.info("这是初始化方法的日志打印");
System.out.println("string.str1:" + str1);
System.out.println("string.str2:" + str2);
System.out.println("string.str3:" + str3);
}
@RequestMapping("/readport")
public String readPort() {
//日志打印
logger.info("这是返回获取配置文件中端口方法的日志打印");
return "port: " + port;
}
@RequestMapping("/sayhello")
public String sayHi() {
//日志打印
logger.info("这是访问方法时的日志打印");
return "Hello World!";
}
}



日志格式: 日志打印时间 + 日志打印级别 + 线程ID + 线程名称 + 执行的类名 + 日志输出信息
日志级别分类
日志级别的顺序

越往上 , 接收到的消息越少(下打印的信息包含上的信息)

application.yml代码
# 配置日志打印等级
logging:
level:
root: trace
UserController.java代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
@RestController
@RequestMapping("/user")
public class UserController {
//首先获取日志对象
//不要导错包了.
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
private static Logger logger = LoggerFactory.getLogger(UserController.class);
@Value("${string.str1}")
private String str1;
@Value("${string.str2}")
private String str2;
@Value("${string.str3}")
private String str3;
//初始化调用
@PostConstruct
public void postConstruct() {
//不同等级日志打印
logger.trace("这是初始化方法的日志打印");
logger.debug("这是初始化方法的日志打印");
logger.info("这是初始化方法的日志打印");
logger.warn("这是初始化方法的日志打印");
logger.error("这是初始化方法的日志打印");
// fatal等级日志, 由于程序已经退出, 所以也就不会有打印了
System.out.println("string.str1:" + str1);
System.out.println("string.str2:" + str2);
System.out.println("string.str3:" + str3);
}
}


application.yml代码
# 配置日志打印等级 + # 设置日志文件的目录
logging:
file:
path: D:\home\ruoyi # 日志文件保存位置
level:
root: trace
设置文件保存的名称(名称里就可以包含了文件的目录, 所以目录配置就可以省略)

application.yml代码
# 配置日志打印等级 + # 设置日志文件保存的名称 + # 设置日志文件的目录
logging:
file:
# path: D:\home\ruoyi # 日志文件保存位置
name: D:\home\ruoyi\spring-1204.log # 日志文件保存名称(内涵日志位置)
level:
root: trace

依赖地址: https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.20
依赖内容:
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
使用注解代替一行代码, 节省工作量(毕竟程序员很累的)

UserService.java代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 使用更简便的得到日志的方法:注解
*/
//@Service 设置为它无法直接访问路由
@Controller//此处没有它就无法访问路由
@ResponseBody
//此处方法没有返回任何信息,没有它就会返回500页面(因为方法无返回内容)
@Slf4j//代替了获取日志对象 (默认名称为log)
public class UserService {
//得到日志对象 注解代替了下面的代码
// private static final Logger log = LoggerFactory.getLogger(UserService.class);
@RequestMapping("/sayhello")
public void sayhello(){
//名称同样为 log
log.trace("我是sayhello trace");
log.debug("我是sayhello debug");
log.info("我是sayhello info");
log.warn("我是sayhello warn");
log.error("我是sayhello error");
}
}
| 基本注解 | 作⽤ |
|---|---|
| @Getter | ⾃动添加 getter ⽅法 |
| @Setter | ⾃动添加 setter ⽅法 |
| @ToString | ⾃动添加 toString ⽅法 |
| @EqualsAndHashCode | ⾃动添加 equals 和 hashCode ⽅法 |
| @NoArgsConstructor | ⾃动添加⽆参构造⽅法 |
| @AllArgsConstructor | ⾃动添加全属性构造⽅法, 顺序按照属性的定义顺序 |
| @NonNull | 属性不能为 null |
| @RequiredArgsConstructor | ⾃动添加必需属性的构造⽅法, final + @NonNull 的 属性为必需 |
| @Data | @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor |
| @Slf4j | 添加⼀个名为 log 的⽇志, 使⽤ slf4j |
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
我有一个类unzipper.rb,它使用Rubyzip解压文件。在我的本地环境中,我可以成功解压缩文件,而无需使用require'zip'明确包含依赖项但是在Heroku上,我得到一个NameError(uninitializedconstantUnzipper::Zip)我只能通过使用明确的require来解决问题:为什么这在Heroku环境中是必需的,但在本地主机上却不是?我的印象是Rails自动需要所有gem。app/services/unzipper.rbrequire'zip'#OnlyrequiredforHeroku.Workslocallywithout!class
我将gem推送到rubygems.org,当我执行“geminstall(gem)”时出现此错误:ERROR:Whileexecutinggem...(NameError)uninitializedconstantPsych::Syck我可以执行“gembuild(gem).gemspec”来生成本地gem,然后geminstall(gem).gem并且安装正常。我还可以将gem放入我的Rails应用程序的Gemfile中,并带有指向Github存储库的指针,这也可以。我试过在多台计算机上安装gem(来自rubygems.org,它们都遇到相同的错误。我不知道是什么原因导致从r
我写了很多initialize代码,将attrs设置为参数,类似于:classSiteClientattr_reader:login,:password,:domaindefinitialize(login,password,domain='somedefaultsite.com')@login=login@password=password@domain=domainendend有没有更像Ruby的方式来做到这一点?我觉得我在一遍又一遍地编写相同的样板设置代码。 最佳答案 您可以使用rubyStruct:classMyClass或
我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li