一个最简单的springboot项目开发步骤
第一步是先创建一个普通的maven工程
第二步是导入依赖
4.0.0 com.hty springboot-01-helloworld 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.6.4 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin
第三步就是编写主启动类
//这个注解说明这是一个springboot应用 这个类叫做主程序类
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
}
}
第四步编写controller 注:所有的包都必须放在主启动类同级包下
@RestController
public class HelloController {
@RequestMapping(value = "/hello")
public String handle01(){
return "hello springboot";
}
}
最后运行主启动类就行
springboot部署的方法很简单,只需要使用maven的package命令打成jar包,然后直接在控制台使用java -jar 命令执行这个jar包就行
注:一定要导入打包依赖才行
2、依赖管理的自动配置 2.1、依赖管理每一个springboot都有一个父项目,父项目做依赖管理
org.springframework.boot spring-boot-starter-parent 2.6.4
这个父项目还有一个父项目
org.springframework.boot spring-boot-dependencies 2.6.4
spring-boot-dependencies这个父项目中包含了所有我们可能会用到的jar包
开发导入starter场景启动器
在springboot开发中会见到spring-boot-starter-*之类的jar包,*就代表的是某种场景,只要引入starter这个场景的所有常规需要的依赖就会自动引入
若官方的starter不满足需求,我们也可以自己自定义starter,但是不能以sprint-boot开头
所有场景启动器最底层的依赖
org.springframework.boot spring-boot-starter 2.6.4 compile
无需关注版本号,自动版本仲裁
引入依赖默认都可以不写版本号
可以修改版本号
在开发中,我们可以不想使用自带的jar包版本,修改版本的办法是,先去父项目中的properties标签中,找到要修改的jar包的标签,然后去自己的项目的pom文件,仿照父项目的写法,将自己的版本号填入即可
2.2、自动配置自动配置好了tomcat,在前面引入webstarter的时候就已经引入了tomcat依赖
自动配置好了springMVC,自动配置好了springmvc的常用功能,如字符编码问题
默认的包结构,主程序所在的包及其下面的所有子包里面的组件都会被默认扫描进来,如果想要改变扫描路径有两种方式
//方式一
@SpringBootApplication(scanBasePackages="com.hty")
//方式二
@ComponentScan("com.hty")
各种配置都有默认值,默认配置最终都是映射到某一个类上,配置文件的值最终会绑定到某个类上,这个类会在容器中有创建对象,springboot所有的自动配置功能都在spring-boot-autoconfigure包里面
3、注解 3.1、@Contiguration标记一个类为springboot中的配置类,我们使用一个案例来进行解析
目前我们有一个User实体类,其中的构造和get,set方法在这里就省略,自行添加即可
public class User {
private String name;
private Integer age;
}
在spring中,将一个实体类添加为bean的方法就是创建一个配置文件,然后在配置文件中进行配置,在springboot中我们可以创建一个配置类就相当于创建了一个配置文件,在config包下创建MyConfig配置类
@Configuration(proxyBeanMethods = true)//告诉springboot这是一个配置类 == 配置文件
public class MyConfig {
@Bean("user") //以方法名作为组件的id 返回类型就是组件类型 创建的对象就是组件
public User user01(){
return new User("zhangsan",18);
}
}
之后在主启动类中进行测试
//这个注解说明这是一个springboot应用 这个类叫做主程序类
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//返回一个ioc容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//查看容器里面的所有组件
String[] beanDefinitionNames = run.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
User user1 = run.getBean("user", User.class);
User user2 = run.getBean("user", User.class);
System.out.println(user1 == user2);//true 说明此时是单例模式
}
}
3.2、@Import
给容器中导入一个组件 需要写在组件类的上面 参数是一个数组,可以将需要导入的组件写在里面,springboot就会在容器中创建这些组件,导入的组件的默认名称为全类名
@Import({User.class})
@Configuration(proxyBeanMethods = false)
public class MyConfig {}
3.3、@Conditional
条件装配,满足Conditional指定的条件则进行组件注入,Conditional是一个根注解,下面有很多的衍生注解
@ConditionalOnBean(name = "tom")
@Bean("user") //以方法名作为组件的id 返回类型就是组件类型 创建的对象就是组件
public User user(){
return new User();
}
//@Bean("tom")
public Pet pet(){
return new Pet();
}
3.3、@ImportResource
引入原生配置文件,可以将xml配置文件中的bean迁移为配置类中的使用@Bean注解配置的组件
@ImportResource("classpath:beans.xml")//导入resources目录下的beans.xml的spring配置文件
public class MyConfig {}
3.4、@ConfigurationProperties
配置绑定,利用这个注解可以读取到配置文件中的属性,但是要注意,需要让配置绑定的类称为一个组件才能访问配置文件中的内容
方式一 :@ConfigurationProperties+@Component
首先我们创建一个实体类
@Component//需要将其加入为一个组件才能使用springboot中的内容
@ConfigurationProperties(prefix = "mycar")//prefix表示以这个为前缀的所有属性
public class Car {
private String brand;
private Integer price;
}
编写配置文件中的内容
# 汽车的信息 mycar.brand=BYD mycar.price=100000
此时配置文件中的属性就已经注入进实体类了
方式二 :@ConfigurationProperties+@EnableConfigurationProperties
@EnableConfigurationProperties注解需要写在配置类上并指定需要开启属性配置功能的类
@EnableConfigurationProperties(Car.class)//开启car的属性配置功能 并将car这个组件导入容器中
public class MyConfig {}
之后在实体类上加入@ConfigurationProperties注解,和前面的例子一样
4、自动配置原理 4.1、主启动类注解在主启动类中的@SpringBootApplication相当于一下三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
4.1.1、@SpringBootConfiguration
查看源码可以发现,其实底层就是一个@Configuration,代表当前是一个配置类,也就是说,主启动类也是springboot中的一个配置类
4.1.2、@ComponentScan指定扫描哪些包中的组件
4.2.3、@EnableAutoConfiguration查看源码,发现主要是这两个注解
@AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class)5、简化开发的工具jar 5.1、lombok
简化javabean的开发,我们不需要手写bean中的一些方法,首先引入lombok的依赖
org.projectlombok lombok
我们还需要安装一个插件来使用lombok
lombok的使用
@NoArgsConstructor//无参构造
@AllArgsConstructor//有参构造
@ToString//生成toString
@Data//生成get和set方法
@EqualsAndHashCode//重写equals和hashcode方法
public class Car {
private String brand;
private Integer price;
}
要注意:lombok并不是添加注解之后直接生成这些方法,而是在编译的时候生成这些方法
若需要创建只包含个别属性的构造函数,那就需要自己手写
@Slf4j日志注解的使用
我们在平时的调试中会使用输出语句进行调试,使用lombok的@Slf4j注解就可以不使用输出语句来输出,直接使用自带的log属性就可以输出日志信息,这个日志也分为很多种类
5.2、dev-tools[官方文档][https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools]
引入依赖
org.springframework.boot spring-boot-devtools true
dev-tools可以实现springboot项目的热部署,以后项目只要出现改变,我们就可以直接按快捷键ctrl+F9就可以进行热部署,但是实际上仍然是重启,与手动点击重启是一样的效果
5.3、Spring Initailizr真正的热部署是需要进行付费服务
这个就是直接可以在idea的项目创建页面直接创建一个springboot的工程
6、springboot的配置文件springboot兼容yaml格式配置文件,这种格式的配置文件非常适合用来做以数据为中心的配置文件
6.1、基本的语法key: value; kv之间有空格
大小写敏感
使用缩进表示层级
缩进不允许使用tab,只允许空格
缩进的空格数不重要,只要相同层级的元素左对齐即可
'#'表示注释
单引号与双引号表示字符串内容,单引号中的换行符会被当做普通字符串输出,但是双引号中的换行符就会产生换行效果
6.2、数据类型字面量:单个的,不可再分的值,date boolean string number null
k: v
对象:键值对的集合,map,hash,set,object
行内写法 k: {k1:v1,k2:v2,k3:v3}
或者
k:
k1: v1
k2: v2
k3: v3
数组:一组按次序排列的值 array、list、queue
行内写法 k: [v1,v2,v3] 或者 k: - v1 - v2 - v3
案例
我们定义两个实体类–人类和宠物类
@Component
@ConfigurationProperties(prefix = "person")
@Data
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private Pet pet;
private String[] interests;
private List animal;
private Map score;
private Set salarys;
private Map> allPets;
}
@Data
public class Pet {
private String name;
private Double weight;
}
之后我们在配置文件中进行赋值
person:
userName: zhangsan
boss: true
birth: 2019/12/9
age: 18
interests: [篮球,足球]
animal:
- cat
- dog
score:
english: 80
math: 90
salarys: [123123.12312,123123.123123]
pet:
name: xiaogou
weight: 99.99
allPets:
sick:
- {name: xiaogou,weight: 99.99}
- name: xiaomao
weight: 88
- name: xiaoniao
weight: 11
health:
- {name: xiaogou,weight: 99.99}
- name: xiaomao
weight: 88
- name: xiaoniao
weight: 11
6.3、自定义配置提示功能
我们在使用spring原生的yaml配置的时候就会有补全提示,但是我们写自己的配置时没有提示,解决方法就是给类上加配置处理器
导入依赖
org.springframework.boot spring-boot-configuration-processor true
刷新pom文件然后重启项目,以后自定义配置就会有自动补全功能了
注:yaml会将属性名比较长的,按照驼峰命名规则命名的属性进行变形,例如userName会变形成user-name
在插件中需要加入
org.springframework.boot spring-boot-maven-plugin org.springframework.boot spring-boot-configuration-processor
这样以后项目部署的时候就不会启动过于缓慢
7、web开发 7.1、静态资源部分 7.1.1、静态资源的访问静态资源的目录可以是/static、/public、/resources、/META-INF/resources,然后访问当前项目的根路径/+静态资源名称就能访问到了
当我们的静态资源名与动态的controller的访问路径一致的时候,会访问动态的资源而不是静态资源,原理就是:静态映射 public class LoginInterceptor implements HandlerInterceptor { //目标方法执行之前 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //登陆检查逻辑 HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser"); if(loginUser != null){ //放行 return true; } //拦截 request.setAttribute("msg","请先登陆"); request.getRequestDispatcher("/login").forward(request,response); return false; } //目标方法执行完成以后 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //页面渲染以后 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
之后在web配置类中对拦截器进行配置
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") //默认拦截的请求 一般都是些/**
.excludePathPatterns(
"/",
"/login",
"/css/**",
"/fonts/**",
"/images/**",
"/js/**"
);//放行的内容
}
}
10、文件上传
前端的写法
Controller层的写法
//MultipartFile自动封装上传过来的文件
@PostMapping(value = "/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestParam("headerImg") MultipartFile headerImg,
@RequestParam("photos") MultipartFile[] photos) throws IOException {
if(!headerImg.isEmpty()){
//保存到文件服务器
String originalFilename = headerImg.getOriginalFilename();//获取文件名
headerImg.transferTo(new File("D:\"+originalFilename));
}
if(photos.length > 0){
for (MultipartFile photo : photos) {
if(!photo.isEmpty()){
String originalFilename = photo.getOriginalFilename();//获取文件名
photo.transferTo(new File("D:\"+originalFilename));
}
}
}
return "main";
}
springboot中封装好了一个文件对象是MultipartFile,直接使用即可
如果文件上传大小太大就会报错,解决方法是在配置文件中进行配置
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=100MB11、注入原生组件
注入servlet,filter和listener
11.1、使用servlet编写一个servlet继承HttpServlet类,在这个类上面添加一个注解@WebServlet(urlPatterns=“/访问地址”)这样就可以注入servlet了
@WebServlet(urlPatterns = "/helloservlet")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("helloservlet");
}
}
我们还需要在主启动类中写一个注解,可以将servlet扫描到
@ServletComponentScan(basePackages = "com.hty")11.2、filter
使用@WebFilter注解来注入,
11.3、listener使用@WebListener注解来注入



