1. 管理工厂对象的创建
1.1 创建单个对象
在springboot中管理单个对象可以直接使用spring框架中注解形式创建。
@Component
@Controller
用来创建控制器对象,直接写在控制器类上@Service
用来创建业务层对象,一般写在Service接口的对应实现类上@Repository
用来创建DAO层对象,此注解一般很少用,DAO接口的实现类在mapper映射文件中实现
- 以上注解都有value属性,value属性用来指定工厂中对象名称,默认名称为类名首字母小写,使用其它的名称时需重新设定,单个属性时可省略value,直接在“”中写对象名称。
@Service
public class DemoServiceImpl implements UserService{
//doing....
}
通过工厂创建之后可以在使用处注入该对象:
@Controller
@RequestMapping("hello")
public class HelloController {
@Autowired
private DemoService demoService;
//doing...
}
1.2 创建多个对象
如何在springboot中像spring框架一样通过xml创建多个对象?在SpringBoot中也提供了相同注解如@Configuration + @Bean
注解进行创建
@Configuration
@Bean
- 默认使用@Bean创建对象在工厂中的唯一标识为方法名称(即复杂对象名称首字母小写作为方法名)
- 修改工厂中对象的唯一标识可以在@Bean("工厂中名字")中的“”内重新指定一个名字
(1)管理复杂对象的创建
@Configuration
public class Beans {
@Bean
public Calendar calendar(){
return Calendar.getInstance();
}
}
(2)使用复杂对象
@Controller
@RequestMapping("hello")
public class HelloController {
@Autowired
private Calendar calendar;
......
}
注意:
1.@Configuration 用来在工厂中一次性创建多个对象,可同时创建简单对象和复杂对象
2.@Component 用来创建单个对象,一般在各层对应的类上使用
1.3 测试
开发BeanConfig
package com.study.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Calendar;
/**
* @ClassName BeanConfig
* @Description 用来进行复杂对象创建
* @Author Jiangnan Cui
* @Date 2022/4/29 12:14
* @Version 1.0
*/
@Configuration //修饰范围:只能作用在类上,代表这是一个配置类,相当于spring.xml
public class BeanConfig {
/**
* 修饰范围: 用在方法上或者注解上
* 作用: 用来将方法返回值交给工厂管理
* 方法名: 推荐返回值首字母小写,代表当前创建对象在工厂中名称
* @return
*/
@Bean
public Calendar calendar(){
return Calendar.getInstance();
}
}
开发Service
package com.study.service;
/**
* @ClassName DemoService
* @Description TODO
* @Author Jiangnan Cui
* @Date 2022/4/29 12:05
* @Version 1.0
*/
public interface DemoService {
void demo();
}
编写Service实现类
package com.study.service;
import org.springframework.stereotype.Service;
/**
* @ClassName DemoServiceImpl
* @Description TODO
* @Author Jiangnan Cui
* @Date 2022/4/29 12:06
* @Version 1.0
*/
/**
* 修饰范围: 用在类上,每次只能创建一个简单对象
* 作用: 在工厂中创建对象
* 默认工厂中名称为类名首字母小写
* value属性: 用来指定当前创建对象在工厂中名称
*/
@Service(value = "demoService")//原始默认对象名为demoServiceImpl
public class DemoServiceImpl implements DemoService{
@Override
public void demo() {
System.out.println("DemoService is Ok");
}
}
开发Controller
package com.study.controller;
import com.study.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Calendar;
/**
* @ClassName DemoController
* @Description 用来测试对象创建
* @Author Jiangnan Cui
* @Date 2022/4/29 12:01
* @Version 1.0
*/
@RestController
@RequestMapping("demo")
public class DemoController {
@Autowired //按照类型注入
private DemoService demoService;
@Autowired //用来修改autowired默认不再根据类型注入,修改为根据名称注入
@Qualifier(value = "demoService")
private DemoService demoService1;
@Autowired
@Qualifier(value = "calendar")
private Calendar calendar;
//测试路径:http://localhost:8888/spring-boot-02/demo/test
//测试结果:浏览器和控制台输出下面对应内容
@RequestMapping("test")
public String test(){
System.out.println("demo ok");
demoService.demo();
demoService1.demo();//两次获取到的是同一个对象,即默认对象的创建方式为单例模型
System.out.println("demoService==demoService1 : " + (demoService==demoService1));
System.out.println("工厂中获取日历对象,当前时间为" + calendar.getTime());
return "Demo Ok!";
}
}
启动项目访问测试路径进行测试:http://localhost:8888/spring-boot-02/demo/test
控制台输出结果:
demo ok
DemoService is Ok
DemoService is Ok
demoService==demoService1 : true
工厂中获取日历对象,当前时间为Fri Apr 29 12:20:00 CST 2022
1.4 总结
2. 属性注入
2.1 基本属性注入
application.yml中给属性赋值,控制器中使用@Value注解完成属性注入
- application.yml
# 声明基本属性注入值
# 1.String+8种基本数据类型
name: 小崔
age: 26
weight: 144.60
birthday: 2012/12/12 12:12:12 # 注意:默认的日期格式为 yyyy/mm/dd HH:MM:ss
sex: true
# 2.数组
arrays: 1,2,3,4,5 # 注意:注入数组元素的时候,多个元素间使用“,”进行分割
# 3.集合
lists: pig,dog,cat,tiger,bee # 规则同数组一致
maps: "{'a':'熊大','b':'熊二','c':'光头强'}" # 注意:注入map集合要使用json形式进行注入,使用@Value注入时必须加入 "#{${属性}}" 进行注入
- InjectionController
package com.study.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @ClassName InjectionController
* @Description 用来测试属性注入
* @Author Jiangnan Cui
* @Date 2022/4/30 9:18
* @Version 1.0
*/
@RestController
@RequestMapping("inject")
public class InjectionController {
//1.测试注入String类型+8种基本类型
@Value("${name}")
private String name;
@Value("${age}")
private Integer age;
@Value("${weight}")
private Double weight;
@Value("${birthday}")
private Date birthday;
@Value("${sex}")
private Boolean sex;
//2.测试数组
@Value("${arrays}")
private String[] arrays;
//3.测试集合
@Value("${lists}")
private List<String> lists;
@Value("#{${maps}}") //注意:在注入map集合时,配置文件中要使用json格式,使用时必须使用"#{${xxx}}"进行获取
private Map<String,String> maps;
//测试路径:http://localhost:8888/spring-boot-02/inject/test
@RequestMapping("test")
public String test(){
System.out.println("inject ok");
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("weight = " + weight);
System.out.println("birthday = " + birthday);
System.out.println("sex = " + sex);
for (String array : arrays) {
System.out.println("array = " + array);
}
for (String list : lists) {
System.out.println("list = " + list);
}
maps.forEach((k,v)-> System.out.println("k = " + k + ", v = " + v));
return "Inject Ok";
}
}
启动服务测试,访问路径:http://localhost:8888/spring-boot-02/inject/test
控制台输出结果:
inject okname = 小崔
age = 26
weight = 144.6
birthday = Wed Dec 12 12:12:12 CST 2012
sex = true
array = 1
array = 2
array = 3
array = 4
array = 5
list = pig
list = dog
list = cat
list = tiger
list = bee
k = a, v = 熊大
k = b, v = 熊二
k = c, v = 光头强
2.2 对象方式注入
application.yml中给属性赋值,控制器中使用 @ConfigurationProperties(prefix="前缀") 注解完成属性注入,注意此种方式必须提供set方法
- pom.xml中引入自定义注入元数据依赖
<!--这个依赖可以根据@ConfigurationProperties注解构建注入元数据--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<!--true代表这个依赖不会被(父子间)传递,仅当前项目可用-->
<optional>true</optional>
</dependency>
解决导入依赖后仍无提示的方法:
1.忘记刷新maven,重新刷新一下
2.重新build一下项目
3.clean一下maven
4.重启idea
......
- application.yml
# 声明对象方式注入 orders:
id: 10
name: 红烧肉
price: 35.38
- InjectionObjectController.java
package com.study.controller;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName InjectionObjectController
* @Description 测试对象注入
* @Author Jiangnan Cui
* @Date 2022/4/30 11:43
* @Version 1.0
*/
@RestController
@RequestMapping("injectObject")
/**
* @ConfigurationProperties 注解
* 修饰范围: 用来类上
* 作用: 用来指定前缀的属性,注入到当前对象中属性名一致的属性中
* 注意: 使用这个注解为属性一次性赋值,必须为属性提供set方法
*/
@ConfigurationProperties(prefix = "orders")
public class InjectionObjectController {
private Integer id;
private String name;
private Double price;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(Double price) {
this.price = price;
}
//测试路径:http://localhost:8888/spring-boot-02/injectObject/test
@RequestMapping("test")
public String test(){
System.out.println("injectObject ok");
System.out.println("id = " + id);
System.out.println("name = " + name);
System.out.println("price = " + price);
return "injectObject ok";
}
}
启动项目进行测试,访问路径:http://localhost:8888/spring-boot-02/injectObject/test
控制台输出结果:
injectObject okid = 10name = 红烧肉
price = 35.38
2.3 SpringBoot与spring注入方式对比
3. JSP模板集成
在SpringBoot框架中默认模板推荐使用Thymeleaf模板,这里我们优先讲与JSP模板进行集成。
3.1 pom.xml中引入jsp的集成jar包
<!--c标签库--> <dependency> <groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--让内嵌tomcat具有解析jsp功能-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
3.2 pom.xml引入jsp运行插件
(注意:使用springboot 2.6.7新建项目时已导入此插件,无需导入)
<!-- springboot插件 1.打包插件,可以以java -jar打包
在打成jar包运行时,必须放入此插件配置,没有插件配置无法运行打包的项目
2.可以正常显示jsp页面
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.3 application.yml配置视图解析器
#在配置文件中引入视图解析器 spring: mvc:
view:
prefix: / # /代表访问项目中webapp中页面
suffix: .jsp
3.4 开发控制器
package com.study.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @ClassName JspController
* @Description 测试jsp模板集成
* @Author Jiangnan Cui
* @Date 2022/4/30 15:50
* @Version 1.0
*/
@Controller
@RequestMapping("jsp")
public class JspController {
//测试路径:http://localhost:8888/spring-boot-02/jsp/test
@RequestMapping("test")
public String test(){
System.out.println("jsp ok");
return "index";
}
}
3.5 开发jsp页面(在main目录下新建webapp文件夹,添加index.jsp)
<%@page pageEncoding="utf-8" contentType="text/html; UTF-8" isELIgnored="false" %> <!doctype html> <html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>springboot</title>
</head>
<body>
<h1>Hello, SpringBoot!</h1>
</body>
</html>
注意:如果新建的jsp页面为空白页面,可使用!+Tab进行模板补全
启动服务进行测试,访问路径:http://localhost:8888/spring-boot-02/jsp/test,若找不到jsp页面,需要在idea中进行配置来启动jsp页面。
注意:使用springboot 2.6.7可以正常加载jsp页面,无需进行下面配置。
3.6 idea中配置jsp页面
- 方式1:使用插件启动访问JSP页面
启动后报错:Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.6.7:run (default-cli) on project spring-boot-02: Application finished with exit code: 1
未解决↑↑↑
- 方式2:在idea中指定工作目录启动访问JSP
启动项目测试,访问路径:http://localhost:8888/spring-boot-02/index.jsp
3.7 配置jsp页面修改后无需重启项目即可自动更新
application.yml
# 公共配置
server:
port: 8888 # 修改内置tomcat服务器的服务端口
servlet:
context-path: /spring-boot-02
jsp:
init-parameters:
development: true # 开启jsp页面开发模式,修改jsp页面无需重启springboot应用即可更新页面