SpringBoot
- 为什么要使用 Spring Boot
- 因为Spring, SpringMVC 需要使用的大量的配置文件 (xml文件)还需要配置各种对象,把使用的对象放入到spring容器中才能使用对象,需要了解其他框架配置规则。
- SpringBoot 就相当于 不需要配置文件的Spring+SpringMVC。 常用的框架和第三方库都已经配置好了。
一、xml和 JavaConfig
- Spring 使用 Xml 作为容器配置文件, 在 3.0 以后加入了 JavaConfig. 使用 java 类做配置文件使用。
1、 JavaConfig
- JavaConfig: 是 Spring 提供的使用 java 类配置容器。 配置 Spring IOC 容器的纯 Java 方法。
- 优点:
- 可以使用面向对象的方式, 一个配置类可以继承配置类,可以重写方法
- 避免繁琐的 xml 配置
2、使用 :
- @Configuration :放在一个类的上面,表示这个类是作为配置文件使用的。
- @Bean:声明对象,把对象注入到容器中。
package com.cooler.config;
import com.cooler.vo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public Student createStudent(){
Student s1 = new Student();
s1.setName("张三");
s1.setAge(20);
s1.setSex("男");
return s1;
}
}
测试:
import com.cooler.config.SpringConfig;
import com.cooler.vo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
@Test
public void test01(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Student student = (Student) ctx.getBean("createStudent");
System.out.println(student);
}
}
3、@ImportResource
- @ImportResource 作用导入其他的xml配置文件, 等于在xml <import resources=“其他配置文件”/>
@Configuration
@ImportResource(value ={ "classpath:applicationContext.xml","classpath:beans.xml"})
public class SpringConfig {
}
4、@PropertyResource
- @PropertyResource 是读取 properties 属性配置文件,在程序代码之外提供数据。
- 步骤:
- 在resources目录下,创建properties文件, 使用k=v的格式提供数据
- 在PropertyResource 指定properties文件的位置
- 使用@Value(value=“${key}”)
@Configuration
@ImportResource(value ={ "classpath:applicationContext.xml","classpath:beans.xml"})
@PropertySource(value = "classpath:config.properties")
@ComponentScan(basePackages = "com.cooler.vo")
public class SpringConfig {
}
以上两个注解使用具体代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myCat" class="com.cooler.vo.Cat">
<property name="name" value="tom猫"/>
<property name="age" value="2" />
<property name="cardId" value="uw532423422"/>
</bean>
</beans>
@Configuration
@ImportResource(value ={ "classpath:applicationContext.xml","classpath:beans.xml"})
@PropertySource(value = "classpath:config.properties")
@ComponentScan(basePackages = "com.cooler.vo")
public class SpringConfig {
@Bean
public Student createStudent(){
Student s1 = new Student();
s1.setName("张三");
s1.setAge(26);
s1.setSex("男");
return s1;
}
@Bean(name = "lisiStudent")
public Student makeStudent(){
Student s2 = new Student();
s2.setName("李四");
s2.setAge(22);
s2.setSex("男");
return s2;
}
tiger.name=\u4E1C\u5317\u8001\u864E
tiger.age=3
@Component("tiger")
public class Tiger {
@Value("${tiger.name}")
private String name;
@Value("${tiger.age}")
private Integer age;
@Override
public String toString() {
return "Tiger{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
二、SpringBoot
1、SpringBoot概述
2、创建SpringBoot项目
(1)第一种方式
- 使用spring boot提供的初始化器,就是向导创建SpringBoot应用
- 使用的地址: https://start.spring.io
(2)第二种方式
- 使用国内的地址:https://start.springboot.io
(3)第三种方式
(4)基于springboot的web例子
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>005-springboot-mvc</artifactId>
<version>1.0.0</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@Controller
public class HelloSpringBoot {
@RequestMapping("/hello")
@ResponseBody
public String helloSpringBoot(){
return "欢迎使用SpringBoot框架";
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3、注解@SpringBootApplication
- 复合注解:由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan组成
- @SpringBootConfiguration
- 使用了@SpringBootConfiguration注解标注的类,可以作为配置文件使用的,可以使用Bean声明对象,注入到容器
- @EnableAutoConfiguration
- 启用自动配置, 把java对象配置好,注入到spring容器中。例如可以把mybatis的对象创建好,放入到容器中
- @ComponentScan
- @ComponentScan 扫描器,找到注解,根据注解的功能创建对象,给属性赋值等等。
- 默认扫描的包: @ComponentScan所在的类所在的包和子包。
4、SpringBoot配置文件
- Spring Boot 的核心配置文件用于配置 Spring Boot 程序,名字必须以 application 开始
- 配置文件名称: application,扩展名有:
- properties( k=v)
- yml ( k: v)
(1)使用application.properties, application.yml
#设置端口号
server.port=8082
#设置访问应用上下文路径, contextpath
server.servlet.context-path=/myboot
server:
port: 8083
servlet:
context-path: /myboot2
(2)多环境配置
- 有开发环境, 测试环境, 上线的环境。
- 每个环境有不同的配置信息, 例如端口, 上下文件, 数据库url,用户名,密码等等
- 使用多环境配置文件,可以方便的切换不同的配置。
- 使用方式: 创建多个配置文件, 名称规则: application-环境名称.properties(yml)
- 创建开发环境的配置文件: application-dev.properties( application-dev.yml )
- 创建测试者使用的配置: application-test.properties
spring:
profiles:
active: test
5、SpringBoot自定义配置
(1)@value
- @Value(“${key}”) , key 来自 application.properties(yml)
@Controller
public class HelloController {
@Value("${server.port}")
private Integer port;
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${school.name}")
private String name;
@Value("${site}")
private String site;
@Resource
private SchoolInfo info;
@RequestMapping("/data")
@ResponseBody
public String queryData(){
return name+",site="+site+", 项目的访问地址="+contextPath+",使用的端口="+port;
}
@RequestMapping("/info")
@ResponseBody
public String queryInfo(){
return "SchoolInfo对象=="+info.toString();
}
}
#port
server.port=8082
#context-path
server.servlet.context-path=/myboot
school.name=Cooler
school.website=www.cooler.com
school.address=江西省
site=www.cooler.com
(2)@ConfigurationProperties
@Component
@ConfigurationProperties(prefix = "school")
public class SchoolInfo {
private String name;
private String website;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "SchoolInfo{" +
"name='" + name + '\'' +
", website='" + website + '\'' +
", address='" + address + '\'' +
'}';
}
}
6、Spring Boot 中使用 JSP
-
SpringBoot不推荐使用jsp ,而是使用模板技术代替jsp -
步骤:
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>009-springboot-jsp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<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>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@Controller
public class JspController {
@RequestMapping("/myjsp")
public String doJsp(Model model){
model.addAttribute("data","SpringBoot使用Jsp");
return "index";
}
}
- 在application.properties文件中配置视图解析器
#配置端口号
server.port=9090
server.servlet.context-path=/myboot
#配置视图解析器
#/ = src/main/webapp
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
7、Spring Boot 中使用 ApplicationContext
- 在 main 方法中 SpringApplication.run()方法获取返回的 Spring 容器对象,再获取业务 bean进行调用。
- 多用在测试
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
UserService userService = (UserService) ctx.getBean("userService");
userService.sayHello("李四");
}
}
8、 ComnandLineRunner 接口 , ApplicationRunner接口
- 开发中可能会有这样的情景。需要在容器启动后执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot 给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为 CommandLineRunner 和 ApplicationRunner。
- 他们的执行时机为容器启动完成的时候。这两个接口中有一个 run 方法,我们只需要实现这个方法即可。
- 这两个接口的不同之处在于: ApplicationRunner 中 run 方 法 的 参 数 为 ApplicationArguments , 而CommandLineRunner接口中 run 方法的参数为 String 数组
ComnandLineRunner 接口
@SpringBootApplication
public class Application implements CommandLineRunner {
@Resource
private HelloService helloService;
public static void main(String[] args) {
System.out.println("准备创建容器对象");
SpringApplication.run(Application.class, args);
System.out.println("容器对象创建之后");
}
@Override
public void run(String... args) throws Exception {
String str = helloService.sayHello("lisi");
System.out.println("调用容器中的对象="+str);
System.out.println("在容器对象创建好,执行的方法");
}
}
三、Spring Boot 和 web 组件
1、SpringBoot 中拦截器
-
拦截器是SpringMVC中一种对象,能拦截对Controller的请求。 -
框架中有系统的拦截器, 还可以自定义拦截器,实现对请求预先处理。 -
实现自定义拦截器步骤:
- 创建类实现SpringMVC框架的HandlerInterceptor接口
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:path="url" />
<bean class="拦截器类全限定名称"/>
</mvc:interceptor>
</mvc:interceptors>
springboot创建拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("执行了LoginInterceptor的preHandle");
return true;
}
}
@Configuration
public class MyAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
HandlerInterceptor interceptor = new LoginInterceptor();
String path []= {"/user/**"};
String excludePath [] = {"/user/login"};
registry.addInterceptor(interceptor)
.addPathPatterns(path)
.excludePathPatterns(excludePath);
}
}
2、使用servlet
-
使用步骤:
- 创建Servlet类,创建类继承HttpServlet
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("===执行的是Servlet==");
out.flush();
out.close();
}
}
@Configuration
public class WebApplictionConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setServlet( new MyServlet());
bean.addUrlMappings("/login","/test");
return bean;
}
}
3、过滤器Filter
-
Filter是Servlet规范中的过滤器,可以处理请求, 对请求的参数, 属性进行调整。 常常在过滤器中处理字符编码 -
在框架中使用过滤器:
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行了MyFilter,doFilter ");
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Configuration
public class WebApplicationConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter( new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
}
4、字符集过滤器
-
CharacterEncodingFilter : 解决post请求中乱码的问题 -
在SpringMVC框架, 在web.xml 注册过滤器,配置属性。 -
第一种方式:
-
使用步骤:
@Configuration
public class WebSystemConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean(){
MyServlet myServlet = new MyServlet();
ServletRegistrationBean reg = new ServletRegistrationBean(myServlet,"/myservlet");
return reg;
}
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean reg = new FilterRegistrationBean();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
filter.setForceEncoding(true);
reg.setFilter(filter);
reg.addUrlPatterns("/*");
return reg;
}
}
- 修改application.properties文件, 让自定义的过滤器起作用
#SpringBoot中默认已经配置了CharacterEncodingFilter。 编码默认ISO-8859-1
#设置enabled=false 作用是关闭系统中配置好的过滤器, 使用自定义的CharacterEncodingFilter
server.servlet.encoding.enabled=false
-
第二种方式
- 修改application.properties文件
server.port=9001
server.servlet.context-path=/myboot
#让系统的CharacterEncdoingFilter生效
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=utf-8
#强制request,response都使用charset属性的值
server.servlet.encoding.force=true
四、ORM 操作 MySQL
- 使用MyBatis框架操作数据, 在SpringBoot框架集成MyBatis
1、第一种方式@Mapper
-
@Mapper:放在dao接口的上面, 每个接口都需要使用这个注解。 -
使用步骤:
- mybatis起步依赖 : 完成mybatis对象自动配置, 对象放在容器中
- pom.xml 指定把src/main/java目录中的xml文件包含到classpath中
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>017-springboot-mapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
public class Student {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 创建Dao接口 StudentDao , 创建一个查询学生的方法
@Mapper
public interface StudentDao {
Student selectById(@Param("stuId") Integer id);
}
- 创建Dao接口对应的Mapper文件, xml文件, 写sql语句
<?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.cooler.dao.StudentDao">
<select id="selectById" resultType="com.cooler.model.Student">
select id,name,age from student where id=#{stuId}
</select>
</mapper>
- 创建Service层对象, 创建StudentService接口和他的实现类。 去dao对象的方法。完成数据库的操作
public interface StudentService {
Student queryStudent(Integer id);
}
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentDao studentDao;
@Override
public Student queryStudent(Integer id) {
Student student = studentDao.selectById(id);
return student;
}
}
- 创建Controller对象,访问Service。
@Controller
public class StudentController {
@Resource
private StudentService studentService;
@RequestMapping("/student/query")
@ResponseBody
public String queryStudent(Integer id){
Student student = studentService.queryStudent(id);
return student.toString();
}
}
- 写application.properties文件,配置数据库的连接信息。
server.port=9001
server.servlet.context-path=/orm
#连接数据库:mysql驱动新版的驱动类
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
@SpringBootTest
class ApplicationTests {
@Test
void contextLoads() {
}
}
2、@MapperSan
- 在 Dao 接口上面加入@Mapper,需要在每个接口都加入注解。当 Dao 接口多的时候不方便。可以使用如下的方式解决。
@SpringBootApplication
@MapperScan(basePackages = {"com.cooler.dao","com.cooler.mapper"})
public class Application {
}
3、mapper 文件和 java 代码分开管理
-
mapper 文件放在 resources 目录下, java 代码放在 src/main/java。
- 在resources目录中创建子目录 (自定义的) , 例如mapper
- 把mapper文件放到 mapper目录中
- 在application.properties文件中,指定mapper文件的目录
#指定mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定mybatis的日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
- 在pom.xml中指定 把resources目录中的文件 , 编译到目标目录中
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
4、事务支持
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>019-springboot-transactional</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<configurationFile>GeneratorMapper.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<classPathEntry location="D:\tools\mysql-connector-java-8.0.22.jar"/>
<context id="tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8"
userId="root"
password="123">
</jdbcConnection>
<javaModelGenerator targetPackage="com.cooler.model"
targetProject="D:\course\25-SpringBoot\springboot-prj\019-springboot-transactional\src\main\java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="false" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.cooler.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<table tableName="student" domainObjectName="Student"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
#设置端口
server.port=9002
#context-path
server.servlet.context-path=/mytrans
#配置数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
#配置mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
#配置日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentMapper studentDao;
@Transactional
@Override
public int addStudent(Student student) {
System.out.println("业务方法addStudent");
int rows = studentDao.insert(student);
System.out.println("执行sql语句");
return rows;
}
}
@Controller
public class StudentController {
@Resource
private StudentService service;
@RequestMapping("/addStudent")
@ResponseBody
public String addStudent(String name,Integer age){
Student s1 = new Student();
s1.setName(name);
s1.setAge(age);
int rows = service.addStudent(s1);
return "添加学生:"+rows;
}
}
@SpringBootApplication
@EnableTransactionManagement
@MapperScan(basePackages = "com.cooler.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
五、接口架构风格—RESTful
- 接口: API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。 用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
- 接口(API):可以指访问servlet,controller的url,调用其他程序的函数
1、REST
(1)概述
-
RESTful架构风格
- REST : (英文: Representational State Transfer , 中文: 表现层状态转移)。
- REST:是一种接口的架构风格和设计的理念,不是标准。
- 优点: 更简洁,更有层次
-
表现层状态转移:
- 表现层就是视图层, 显示资源的, 通过视图页面,jsp等等显示操作资源的结果。
- 状态: 资源变化
- 转移: 资源可以变化的。 资源能创建,new状态, 资源创建后可以查询资源, 能看到资源的内容,这个资源内容 ,可以被修改, 修改后资源 和之前的不一样。
-
URL加上请求方式必须唯一 (2)REST中的要素: -
用REST表示资源和对资源的操作。
- 资源使用url表示的, 在互联网, 使用的图片,视频, 文本,网页等等都是资源。
- 资源是用名词表示。
比如我们要访问一个 http 接口:http://localhost:8080/boot/order?id=1021&status=1
采用 RESTFul 风格则 http 地址为:http://localhost:8080/boot/order/1021/1
-
对资源:
- 查询资源: 看,通过url找到资源。
- 创建资源: 添加资源
- 更新资源:更新资源 ,编辑
- 删除资源: 去除
-
使用http中的动作(请求方式), 表示对资源的操作(CURD)
处理单个资源: 用他的单数方式
http://localhost:8080/myboot/student/1001
http://localhost:8080/myboot/student/1001/1
处理多个资源:使用复数形式
http://localhost:8080/myboot/students/1001/1002
http://localhost:8080/myboot/student
在post请求中传递数据
<form action="http://localhost:8080/myboot/student" method="post">
姓名:<input type="text" name="name" />
年龄:<input type="text" name="age" />
</form>
- PUT: 更新资源 – sql update(浏览器不直接支持)
<form action="http://localhost:8080/myboot/student/1" method="post">
姓名:<input type="text" name="name" />
年龄:<input type="text" name="age" />
<input type="hidden" name="_method" value="PUT" />
</form>
- DELETE: 删除资源 – sql delete
<a href="http://localhost:8080/myboot/student/1">删除1的数据</a>
-
需要的分页, 排序等参数,依然放在 url的后面, 例如
http://localhost:8080/myboot/students?page=1&pageSize=20
- 一句话说明REST: 使用url表示资源 ,使用http动作操作资源。
2、注解支持
- @PathVariable : 从url中获取数据
- @GetMapping: 支持的get请求方式,等同于 @RequestMapping( method=RequestMethod.GET)
- @PostMapping: 支持post请求方式 ,等同于 @RequestMapping( method=RequestMethod.POST)
- @PutMapping: 支持put请求方式,等同于 @RequestMapping( method=RequestMethod.PUT)
- @DeleteMapping: 支持delete请求方式,等同于 @RequestMapping( method=RequestMethod.DELETE)
- @RestController: 符合注解, 是@Controller和@ResponseBody组合。
- 在类的上面使用@RestController , 表示当前类者的所有方法都加入了 @ResponseBody
@RestController
public class MyRestController {
@GetMapping("/student/{stuId}")
public String queryStudent(@PathVariable("stuId") Integer studentId){
return "查询学生studentId="+studentId;
}
@PostMapping("/student/{name}/{age}")
public String createStudent(@PathVariable("name") String name,
@PathVariable("age") Integer age){
return "创建资源 student: name="+name+"#age="+age;
}
@PutMapping("/student/{id}/{age}")
public String modifyStudent(@PathVariable Integer id,
@PathVariable Integer age){
return "更新资源, 执行put请求方式: id="+id+"#age="+age;
}
@DeleteMapping("/student/{id}")
public String removeStudentById(@PathVariable Integer id){
return "删除资源,执行delete, id="+id;
}
}
3、Postman : 测试工具
- 使用Postman : 可以测试 get ,post , put ,delete 等请求
4、在页面中或者ajax中,支持put,delete请求
-
在SpringMVC中 有一个过滤器, 支持post请求转为put ,delete -
过滤器:org.springframework.web.filter.HiddenHttpMethodFilter -
作用:把请求中的post请求转为 put , delete -
实现步骤:
- application.properties(yml) : 开启使用 HiddenHttpMethodFilter 过滤器
server.port=9001
server.servlet.context-path=/myredis
#启用支持put,delete
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=123
- 在请求页面中,包含 _method参数, 他的值是 put, delete ,发起这个请求使用的post方式
<form action="student/test" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="测试请求方式">
</form>
六、SpringBoot集成Redis
- Spring,SpringBoot中有 一个RedisTemplate(StringRedisTemplate),处理和redis交互
- RedisTemplate 使用的 lettuce 客户端库
- 在程序中使用RedisTemplate类的方法 操作redis数据, 实际就是调用的lettuce 客户端的中的方法
1、配置Windows版本的redis
- Redis-x64-3.2.100.rar 解压缩到一个非中文的目录
- redis-server.exe:服务端, 启动后,不要关闭
- redis-cli.exe:客户端, 访问redis中的数据
- redisclient-win32.x86_64.2.0.jar : Redis图形界面客户端
- 执行方式: 在这个文件所在的目录, 执行 java -jar redisclient-win32.x86_64.2.0.jar
2、使用
-
需求:完善根据学生 id 查询学生的功能,先从 redis 缓存中查找,如果找不到,再从数据库中查找,然后放到 redis 缓存中 -
步骤:
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>021-springboot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server.port=9001
server.servlet.context-path=/myredis
#指定Redis
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=123
@RestController
public class RedisController {
@Resource
private RedisTemplate redisTemplate;
@Resource
private StringRedisTemplate stringRedisTemplate;
@PostMapping("/redis/addstring")
public String addToRedis(String name, String value){
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set("myname","lisi");
return "向redis添加string类型的数据";
}
@GetMapping("/redis/getk")
public String getData(String k){
ValueOperations valueOperations = redisTemplate.opsForValue();
Object v = valueOperations.get(k);
return "key是"+k+",他的值是:"+v;
}
@PostMapping("/redis/{k}/{v}")
public String addStringKV(@PathVariable String k,
@PathVariable String v){
stringRedisTemplate.opsForValue().set(k,v);
return "使用StringRedisTemplate对象";
}
@GetMapping("/redis/getstr/{k}")
public String getStringValue(@PathVariable String k){
String v = stringRedisTemplate.opsForValue().get(k);
return "k的value:"+v;
}
@PostMapping("/redis/addstr")
public String addString(String k,String v){
redisTemplate.setKeySerializer( new StringRedisSerializer());
redisTemplate.setValueSerializer( new StringRedisSerializer());
redisTemplate.opsForValue().set(k,v);
return "定义RedisTemplate对象的key,value的序列化";
}
@PostMapping("/redis/addjson")
public String addJson(){
Student student = new Student();
student.setId(1001);
student.setName("zhangsan");
student.setAge(20);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer( new Jackson2JsonRedisSerializer(Student.class) );
redisTemplate.opsForValue().set("mystudent", student);
return "json序列化";
}
@PostMapping("/redis/getjson")
public String getJson(){
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer( new Jackson2JsonRedisSerializer(Student.class) );
Object obj = redisTemplate.opsForValue().get("mystudent");
return "json反序列化="+ obj;
}
}
3、对比 StringRedisTemplate 和 RedisTemplate
- StringRedisTemplate:把k,v 都是作为String处理,使用的是String的序列化 ,可读性好。
- RedisTemplate:把k,v 经过了序列化存到redis。k,v 是序列化的内容,不能直接识别。默认使用的jdk序列化,可以修改为前提的序列化
- 序列化:把对象转化为可传输的字节序列过程称为序列化。
- 反序列化:把字节序列还原为对象的过程称为反序列化。
- 为什么需要序列化:
- 序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而进行跨平台存储和网络传输的方式就是IO,IO支持的数据格式就是字节数组。必须在把对象转成字节数组的时候就制定一种规则(序列化),那么从IO流里面读出数据的时候再以这种规则把对象还原回来(反序列化)。
- 什么情况下需要序列化:
- 凡是需要进行“跨平台存储”和”网络传输”的数据,都需要进行序列化。本质上存储和网络传输 都需要经过 把一个对象状态保存成一种跨平台识别的字节格式,然后其他的平台才可以通过字节信息解析还原对象信息。
- 序列化的方式:
- 序列化只是一种拆装组装对象的规则,那么这种规则肯定也可能有多种多样,比如现在常见的序列化方式有:JDK(不支持跨语言)、JSON、XML、Hessian、Kryo(不支持跨语言)、Thrift、Protofbuff、
java的序列化: 把java对象转为byte[], 二进制数据
json序列化:json序列化功能将对象转换为 JSON 格式或从 JSON 格式转换对象。
例如把一个Student对象转换为JSON字符串{"name":"李四", "age":29} )
反序列化(将JSON字符串 {"name":"李四", "age":29} 转换为Student对象)
七、SpringBoot集成Dubbo
- 阿里巴巴提供了 dubbo 集成 springBoot 开源项目,可以到 GitHub 上 https://github.com/apache/dubbo-spring-boot-project 查看入门教程
使用
(1)接口项目,公共项目(一个普通的maven项目)
public class Student implements Serializable {
private static final long serialVersionUID = 1901229007746699151L;
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 接口service——StudentService
public interface StudentService {
Student queryStudent(Integer id);
}
(2)提供者模块(SpringBoot项目)
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>023-service-provider</artifactId>
<version>1.0.0</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.cooler</groupId>
<artifactId>022-interface-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 实现接口Service——impl——StudentServiceImpl
@DubboService(interfaceClass = StudentService.class,version = "1.0",timeout = 5000)
public class StudentServiceImpl implements StudentService {
@Override
public Student queryStudent(Integer id) {
Student student = new Student();
if( 1001 == id){
student.setId(1001);
student.setName("------1001-张三");
student.setAge(20);
} else if(1002 == id){
student.setId(1002);
student.setName("#######1002-李四");
student.setAge(22);
}
return student;
}
}
#配置服务名称 dubbo:application name="名称"
spring.application.name=studentservice-provider
#配置扫描的包
dubbo.scan.base-packages=com.cooler.service
#dubbo的协议和端口号
#dubbo.protocol.name=dubbo
#dubbo.protocol.port=20881
#注册中心
dubbo.registry.address=zookeeper://localhost:2181
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
(3)消费者模块
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>024-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.cooler</groupId>
<artifactId>022-interface-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@RestController
public class DubboController {
@DubboReference(version = "1.0")
private StudentService studentService;
@GetMapping("/query")
public String queryStudent(Integer id){
Student student = studentService.queryStudent(id);
return "调用远程接口,获取对象:"+student;
}
}
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
#指定服务名称
spring.application.name=consumer-application
#指定注册中心
dubbo.registry.address=zookeeper://localhost:2181
#指定扫描的包
dubbo.scan.base-packages=com.cooler.controller
八、Spring Boot 打包
- Spring Boot 可以打包为 war 或 jar 文件。 以两种方式发布应用
1、打包成war
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>025-springboot-war</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<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>
</dependencies>
<build>
<finalName>myboot</finalName>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server.port=9001
server.servlet.context-path=/myjsp
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
@SpringBootApplication
public class JspApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(JspApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(JspApplication.class);
}
}
2、打包成jar
<?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.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>026-springboot-jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<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>
</dependencies>
<build>
<finalName>myboot</finalName>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.2.RELEASE</version>
</plugin>
</plugins>
</build>
</project>
@Controller
public class HelloController {
@RequestMapping("/hello")
public ModelAndView hello(){
ModelAndView mv = new ModelAndView();
mv.addObject("data","SpringBoot打包为jar");
mv.setViewName("main");
return mv;
}
}
3、区别
- war:服务器占用资源比较多,但是能够充分利用服务器的能力
- jar:轻巧简单,内嵌的服务器性能比不上使用独立的服务器。
九、Thymeleaf模板
1、认识Thymeleaf
- Thymeleaf:是使用java开发的模板技术,在服务器端运行。把处理后的数据发送给浏览器。
- 模板是作视图层工作的,显示数据的。Thymeleaf是基于Html语言。
- Thymleaf语法是应用在html标签中 。SpringBoot框架集成Thymealeaf, 使用Thymeleaf代替jsp。
2、运用Thymeleaf的第一个例子
@Controller
public class HelloThymeleafController {
@GetMapping("/hello")
public String helloThymeleaf(Model model,HttpServletRequest request){
request.setAttribute("data","欢迎使用Thymeleaf模板引擎");
model.addAttribute("mydata","model中的数据");
return "hello";
}
}
- resources——templates——hello.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello.html</title>
</head>
<body>
<h3>使用Thymeleaf的例子</h3>
<p th:text="${data}">
显示数据:
</p>
<p th:text="${mydata}">
显示数据:
</p>
</body>
</html>
- 没有经过服务器时,即没有使用Thymeleaf模板时,直接显示的是“显示数据”,使用了之后,该文字不再显示,显示的是request中所存的数据“data"——“欢迎使用Thymeleaf模板引擎”
- 模板引擎的常用设置
#在开发阶段,关闭模板引擎,让修改立即生效
spring.thymeleaf.cache=false
#编码格式
spring.thymeleaf.encoding=utf-8
#模板类型(默认是HTML)
spring.thymeleaf.mode=HTML
#模板的前缀
spring.thymeleaf.prefix=classpath:/templates/
#模板后缀
spring.thymeleaf.suffix=.html
3、表达式
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/>
</parent>
<groupId>com.cooler</groupId>
<artifactId>028-thymeleaf-course</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(1)标准变量表达式
- 语法: ${key}
- 作用: 获取key对于的文本数据, key 是request作用域中的key , 使用request.setAttribute(), model.addAttribute()
- 在页面中的 html标签中, 使用 th:text=“${key}”
<div style="margin-left: 400px">
<h3>标准变量表达式: ${key}</h3>
<p th:text="${site}">key不存在</p>
<br/>
<p>获取SysUser对象 属性值</p>
<p th:text="${myuser.id}">id</p>
<p th:text="${myuser.name}">姓名</p>
<p th:text="${myuser.sex}">性别:m男</p>
<p th:text="${myuser.age}">年龄</p>
<p th:text="${myuser.getName()}">获取姓名使用getXXX</p>
</div>
(2)选择变量表达式( 星号变量表达式)
- 语法: *{key}
- 作用: 获取这个key对应的数据, *{key}需要和th:object 这个属性一起使用。目的是简单获取对象的属性值。
<p>使用 *{} 获取SysUser的属性值</p>
<div th:object="${myuser}">
<p th:text="*{id}"></p>
<p th:text="*{name}"></p>
<p th:text="*{sex}"></p>
<p th:text="*{age}"></p>
</div>
<p>使用*{}完成的表示 对象的属性值</p>
<p th:text="*{myuser.name}" ></p>
(3)链接表达式
-
语法: @{url} -
作用: 表示链接, 可以如下
<script src="..."> ,
<link href="...">
<a href=".."> ,
<form action="...">
<img src="...">
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>链接表达式</title>
</head>
<body>
<h3>链接绝对路径</h3>
<a th:href="@{http://www.baidu.com}">链接到百度</a>
<h3>链接的是相对地址</h3>
<a th:href="@{/tpl/queryAccount}">相对地址,没有参数</a>
<h3>链接的相对地址,使用字符串链接传递参数</h3>
<a th:href="@{'/tpl/queryAccount?id='+ ${userId} }">获取model中数据</a>
<h3>推荐使用的传参数的方式</h3>
<a th:href="@{/tpl/queryAccount(id=${userId})}">传参数</a>
<h3>传递多个参数</h3>
<a th:href="@{/tpl/queryUser(name='lisi',age=20)}">传多个参数</a>
</body>
</html>
4、Thymeleaf属性
- 属性是放在html元素中的,就是html元素的属性,加入了th前缀,属性的作用不变。加上th, 属性的值由模板引擎处理。 在属性可以使用变量表达式。例如:
<form action="/loginServlet" method="post"></form>
<form th:action="/loginServlet" th:method="${methodAttr}"></form>
(1)简单
<form id="login" th:action="@{/login}" th:method="post">......</form>
<form id="login" th:action="@{/login}" th:method="post">......</form>
<a th:href="@{/query/student}">相对地址没有传参数</a>
<script type="text/javascript" th:src="@{/js/jquery-3.4.1.js}"></script>
<input type="text" id="realName" name="reaName" th:text="${realName}">
<a th:onclick="'fun1('+${user.id}+')'" th:style="'color:red'">点击我</a>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>属性</title>
<script th:src="@{/js/jquery-3.4.1.js}" type="text/javascript"></script>
</head>
<body>
<div style="margin-left: 400px">
<h3>属性使用, 在html元素的属性上加入th</h3>
<form th:action="@{/loginServlet}" th:method="${methodAttr}">
<input th:type="text" th:name="${paramname}" th:value="${uservalue}"> <br/>
<input type="button" id="btn" th:onclick="btnClick()" value="按钮">
</form>
<p th:style="${textcolor}">这是模板的例子</p>
</div>
</body>
<script type="text/javascript">
function btnClick(){
alert("按钮单击了");
}
$(function(){
$("#btn").click(function(){
alert("click===jquery")
})
})
</script>
</html>
(2)th:each
- each循环, 可以循环List,Array
- 语法:在一个html标签中,使用th:each
<div th:each="集合循环成员,循环的状态变量:${key}">
<p th:text="${集合循环成员}" ></p>
</div>
集合循环成员,循环的状态变量:两个名称都是自定义的。
“循环的状态变量”这个名称可以不定义,默认是"集合循环成员Stat"
th:each="user, iterStat : ${userlist}"中:
? iterStat
${userList} 循环体的信息,通过该变量可以获取如下信息:
index: 当前迭代对象的 index(从 0 开始计算)
count: 当前迭代对象的个数(从 1 开始计算)这两个用的较多
size: 被迭代对象的大小
current: 当前迭代变量
even/odd: 布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
first: 布尔值,当前循环是否是第一个
last: 布尔值,当前循环是否是最后一个
注意:循环体信息 iterStat 也可以不定义,则默认采用迭代变量加上 Stat 后缀,即userStat
①循环List
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>each循环</title>
</head>
<body>
<div style="margin-left: 400px">
<br/>
<br/>
<table border="1" cellpadding="0" cellspacing="0">
<thead>
<tr>
<td> 编号</td>
<td> id 序号 </td>
<td> name </td>
<td> sex </td>
<td> age </td>
<td>姓名</td>
<td>是否是第一行</td>
</tr>
</thead>
<tbody>
<tr th:each="user:${myusers}">
<td th:text="${userStat.count}+'/'+${userStat.size}"></td>
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.sex}"></td>
<td th:text="${user.age}"></td>
<td th:text="${userStat.current.name}"></td>
<td th:text="${userStat.first}"/>
</tr>
</tbody>
</table>
</div>
</body>
</html>
②循环Array
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>each循环</title>
</head>
<body>
<div style="margin-left: 400px">
<div th:each="user:${userarray}">
<p th:text="${user.id}"></p>
<p th:text="${user.name}"></p>
<p th:text="${user.sex}"></p>
<p th:text="${user.age}"></p>
<br/>
<hr/>
</div>
</div>
</body>
</html>
和循环List一样
③each循环Map
<div th:each="集合循环成员,循环的状态变量:${key}">
<p th:text="${集合循环成员.key}" ></p>
<p th:text="${集合循环成员.value}" ></p>
</div>
集合循环成员,循环的状态变量:两个名称都是自定义的。 “循环的状态变量”这个名称可以不定义,默认是"集合循环成员Stat"
key:map集合中的key
value:map集合key对应的value值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>循环Map</title>
</head>
<body>
<div style="margin-left: 400px">
<div th:each="map,userStat:${mymap}">
<p th:text="${map.key}"></p>
<p th:text="${map.value}" ></p>
<p th:text="${map.value.id}"></p>
<p th:text="${map.value.name}"></p>
<p th:text="${userStat.index}"></p>
<br/>
<hr/>
</div>
<br/>
<br/>
</div>
</body>
</html>
④List<Map<String,user>>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>循环Map</title>
</head>
<body>
<div style="margin-left: 400px">
<h3>循环List《Map》 Map<String,SysUser> lm: listmap.get(0)</h3>
<div th:each="lm:${listmap}">
<div th:each="m:${lm}">
<p th:text="${m.key}"></p>
<p th:text="${m.value.id}"></p>
<p th:text="${m.value.name}"></p>
<p th:text="${m.value.age}"></p>
<br/>
<hr/>
</div>
<br>
<hr>
</div>
</div>
</body>
</html>
(3)条件判断if
- “th:if” : 判断语句, 当条件为true, 显示html标签体内, 反之不显示,没有else语句
语法:
<div th:if=" 10 > 0 "> 显示文本内容 </div>
<div style="margin-left: 400px">
<h3> if 使用</h3>
<p th:if="${sex=='m'}">性别是男</p>
<p th:if="${isLogin}">已经登录系统</p>
<p th:if="${age > 20}">年龄大于20</p>
<p th:if="${name}">name是“”</p>
<p th:if="${isOld}"> isOld是null</p>
</div>
- 还有一个 th:unless 和 th:if相反的行为
语法:
<div th:unless=" 10 < 0 "> 当条件为false显示标签体内容 </div>
<div style="margin-left: 400px">
<h3>unless: 判断条件为false,显示标签体内容</h3>
<p th:unless="${sex=='f'}">性别是男的</p>
<p th:unless="${isLogin}">登录系统</p>
<p th:unless="${isOld}"> isOld是null </p>
</div>
(4)switch,case判断语句
- th:switch 和 java中的switch一样的
语法:
<div th:switch="要比对的值">
<p th:case="值1">
结果1
</p>
<p th:case="值2">
结果2
</p>
<p th:case="*">
默认结果
</p>
以上的case只有一个语句执行
</div>
(5)th:inline
- th:inline 有三个取值类型 (text, javascript 和 none)
①内联text: 在html标签外,获取表达式的值
- 可以让 Thymeleaf 表达式不依赖于 html 标签,直接使用内联表达式[[表达式]]即可获取动态数据
- 要求在父级标签上加 th:inline = “text”属性
- 语法:
<p>显示姓名是:[[${key}]]</p>
<div style="margin-left: 400px">
<h3>内联 text, 使用内联表达式显示变量的值</h3>
<div th:inline="text">
<p>我是[[${name}]],年龄是[[${age}]]</p>
我是<span th:text="${name}"></span>,年龄是<span th:text="${age}"></span>
</div>
<div>
<p>使用内联text</p>
<p>我是[[${name}]],性别是[[${sex}]]</p>
</div>
</div>
②内联javascript
例子:
<script type="text/javascript" th:inline="javascript">
var myname = [[${name}]];
var myage = [[${age}]];
function fun(){
alert("单击事件,获取数据 "+ myname + ","+ [[${sex}]])
}
</script>
5、字面量
<div style="margin-left: 400px">
<h3>文本字面量: 使用单引号括起来的字符串</h3>
<p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p>
<h3>数字字面量</h3>
<p th:if="${20>5}"> 20大于 5</p>
<h3>boolean字面量</h3>
<p th:if="${isLogin == true}">用户已经登录系统</p>
<h3>null字面量</h3>
<p th:if="${myuser != null}">有myuser数据</p>
</div>
6、字符串连接
- 连接字符串有两种语法:
- 语法使用 单引号括起来字符串 ,使用 + 连接其他的字符串或者表达式
<p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p>
<p th:text="|我是${name},我所在城市${city|">
显示数据
</p>
<div style="margin-left: 400px">
<h3>字符串连接方式1:使用单引号括起来的字符串</h3>
<p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p>
<br/>
<br/>
<h3>字符串连接方式2:|字符串和表达式|</h3>
<p th:text="|我是${name},所在城市${city},其他人${myuser.name}|"></p>
</div>
7、运算符
算术运算: + , - - , * , / , %
关系比较: > , < , >= , <= ( gt , lt , ge , le )
相等判断: == , != ( eq , ne )
三元运算符:(三元运算符可以嵌套)
表达式 ? true的结果 : false的结果
<div style="margin-left: 400px">
<h3>使用运算符</h3>
<p th:text="${age > 10}">年龄大于 10 </p>
<p th:text="${ 20 + 30 }">显示运算结果</p>
<p th:if="${myuser == null}">myuser是null</p>
<p th:if="${myuser eq null}">myuser是null</p>
<p th:if="${myuser ne null}">myuser不是null</p>
<p th:text="${isLogin == true ? '用户已经登录' : '用户需要登录'}"></p>
<p th:text="${isLogin == true ? ( age > 10 ? '用户是大于10的' : '用户年龄比较小') : '用户需要登录'}"></p>
</div>
8、基本Thymeleaf对象
@GetMapping("/baseObject")
public String baseObject(Model model, HttpServletRequest request,
HttpSession session){
model.addAttribute("myname","李思");
request.setAttribute("requestData","request作用域中的数据");
request.getSession().setAttribute("sessionData","session作用域中的数据");
session.setAttribute("loginname","zhangsan");
return "baseObject";
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>模板内置对象,方便使用request,session</title>
</head>
<body>
<div style="margin-left: 350px">
<h3>内置对象#request,#session,session的使用</h3>
<p>获取作用域中的数据</p>
<p th:text="${#request.getAttribute('requestData')}"></p>
<p th:text="${#session.getAttribute('sessionData')}"></p>
<p th:text="${session.loginname}"></p>
<br/>
<br/>
<h3>使用内置对象的方法</h3>
getRequestURL=<span th:text="${#request.getRequestURL()}"></span><br/>
getRequestURI=<span th:text="${#request.getRequestURI()}"></span><br/>
getQueryString=<span th:text="${#request.getQueryString()}"></span><br/>
getContextPath=<span th:text="${#request.getContextPath()}"></span><br/>
getServerName=<span th:text="${#request.getServerName()}"></span><br/>
getServerPort=<span th:text="${#request.getServerPort()}"></span><br/>
sessionId,getId=<span th:text="${#session.getId()}"></span>
<h3>param对象:表示请求的参数集合</h3>
name参数的值:<span th:text="${param.name}"></span><br/>
参数的数量:<span th:text="${param.size()}"></span><br/>
</div>
</body>
</html>
9、内置工具类
- 内置工具类型: Thymeleaf自己的一些类,提供对string, date ,集合的一些处理方法
- #dates: 处理日器的工具类
- #numbers:处理数字
- #lists: 处理list集合
@GetMapping("/utilobject")
public String utilObject(Model model){
model.addAttribute("mydate",new Date());
model.addAttribute("mynum",26.695);
model.addAttribute("mystr","cooler");
List<String> list = Arrays.asList("a","b","c");
model.addAttribute("mylist",list);
Zoo zoo = new Zoo();
Cat cat = new Cat();
cat.setName("短腿");
Dog dog = new Dog();
dog.setName("二哈");
zoo.setCat(cat);
model.addAttribute("zoo",zoo);
return "utilObject";
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>内置工具类对象</title>
</head>
<body>
<div style="margin-left: 350px">
<h3>日期类对象 #dates</h3>
<p th:text="${#dates.format(mydate )}"></p>
<p th:text="${#dates.format(mydate,'yyyy-MM-dd')}"></p>
<p th:text="${#dates.format(mydate,'yyyy-MM-dd HH:mm:ss')}"></p>
<p th:text="${#dates.year(mydate)}"></p>
<p th:text="${#dates.month(mydate)}"></p>
<p th:text="${#dates.monthName(mydate)}"></p>
<p th:text="${#dates.createNow()}"></p>
<br/>
<h3>内置工具类#numbers,操作数字的</h3>
<p th:text="${#numbers.formatCurrency(mynum)}"></p>
<p th:text="${#numbers.formatDecimal(mynum,5,2)}"></p>
<br/>
<h3>内置工具类#strings,操作字符串</h3>
<p th:text="${#strings.toUpperCase(mystr)}"></p>
<p th:text="${#strings.indexOf(mystr,'cool')}"></p>
<p th:text="${#strings.substring(mystr,2,5)}"></p>
<p th:text="${#strings.substring(mystr,2)}"></p>
<p th:text="${#strings.concat(mystr,'---A cool man---')}"></p>
<p th:text="${#strings.length(mystr)}"></p>
<p th:text="${#strings.length('hello')}"></p>
<p th:unless="${#strings.isEmpty(mystr)}"> mystring 不是 空字符串 </p>
<br/>
<h3>内置工具类#lists,操作list集合</h3>
<p th:text="${#lists.size(mylist)}"></p>
<p th:if="${#lists.contains(mylist,'a')}">有成员a</p>
<p th:if="!${#lists.isEmpty(mylist)}"> list 集合有多个成员</p>
<br/>
<h3>处理null</h3>
<p th:text="${zoo?.dog?.name}"></p>
</div>
</body>
</html>
10、自定义模板
-
模板是内容复用, 定义一次,在其他的模板文件中多次使用。 -
模板使用:
th:fragment="模板自定义名称"
例如:
<div th:fragment="head">
<p>
CoolEr学习Java
</p>
<p>
www.cooler.com
</p>
</div>
1) ~{templatename :: selector}
templatename: 文件名称
selector: 自定义模板名称
2)templatename :: selector
templatename: 文件名称
selector: 自定义模板名称
对于使用模板:
有包含模板(th:include)
插入模板(th:insert)
-
例子: -
head.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div th:fragment="top">
<p>CoolEr</p>
<p>网站 www.cooler.com</p>
</div>
<div th:fragment="menu">
<p>文档|下载|blog</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
footer.html
@copy; CoolEr2022
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>使用模板</title>
</head>
<body>
<div style="margin-left: 350px">
<h3>使用其他目录中的模板文件</h3>
<div th:insert="common/left :: html"></div>
<br/>
<br/>
<div th:include="common/left"></div>
<div th:insert="head :: menu"></div>
<h3>插入模板 th:insert</h3>
<div th:insert="~{ head :: top }">
</div>
<br/>
<br/>
<h3>插入模板 第二种格式</h3>
<p th:insert="head :: top"></p>
<br/>
<br/>
<h3>包含模板,第一种语法</h3>
<div th:include="~{ head :: top}">
</div>
<br/>
<br/>
<h3>包含模板,第二种语法</h3>
<div th:include="head :: top">
</div>
<br/>
<br/>
<h3>使用整个文件作为复用的内容(整个文件作为模板使用)</h3>
<div th:include="footer :: html"></div>
<br/>
<div th:include="footer" ></div>
<br/>
<div th:insert="footer"></div>
</div>
</body>
</html>
十、总结
1、创建对象的注解
- @Controller: 放在类的上面,创建控制器对象,注入到容器中
- @RestController: 放在类的上面,创建控制器对象,注入到容器中。
- 作用:复合注解是@Controller , @ResponseBody, 使用这个注解类的,里面的控制器方法的返回值都是数据
- @Service : 放在业务层的实现类上面,创建service对象,注入到容器
- @Repository : 放在dao层的实现类上面,创建dao对象,放入到容器。
- 没有使用这个注解,是因为现在使用MyBatis框架,dao对象是MyBatis通过代理生成的。
- @Component: 放在类的上面,创建此类的对象,放入到容器中。
2、属性赋值
- @Value : 简单类型的赋值
- 例如:在属性的上面使用@Value(“李四”) private String name
- 还可以使用@Value,获取配置文件中的数据(properties或yml)——@Value(“${server.port}”) private Integer port
- @Autowired: 引用类型赋值自动注入的,支持byName, byType,默认是byType 。
- 放在属性的上面,也可以放在构造方法的上面。 推荐是放在构造方法的上面
- @Qualifer: 给引用类型赋值,使用byName方式。
(@Autowird, @Qualifer都是Spring框架提供的。) - @Resource : 来自jdk中的定义, javax.annotation。 实现引用类型的自动注入, 支持byName, byType。默认是byName, 如果byName失败,再使用byType注入。
3、其他
- @Configuration : 放在类的上面,表示这是个配置类,相当于xml配置文件
- @Bean:放在方法的上面, 把方法的返回值对象,注入到spring容器中。
- @ImportResource : 加载其他的xml配置文件, 把文件中的对象注入到spring容器中
- @PropertySource : 读取其他的properties属性配置文件
- @ComponentScan: 扫描器 ,指定包名,扫描注解的
- @ResponseBody: 放在方法的上面,表示方法的返回值是数据, 不是视图
- @RequestBody : 把请求体中的数据,读取出来, 转为java对象使用。
- @ControllerAdvice: 控制器增强, 放在类的上面, 表示此类提供了方法,可以对controller增强功能。
- @ExceptionHandler : 处理异常的,放在方法的上面
- @Transcational : 处理事务的, 放在service实现类的public方法上面, 表示此方法有事务
4、SpringBoot中使用的注解
- @SpringBootApplication : 放在启动类上面, 包含了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
5、MyBatis相关的注解
- @Mapper : 放在类的上面 , 让MyBatis找到接口, 创建他的代理对象
- @MapperScan :放在主类的上面 , 指定扫描的包, 把这个包中的所有接口都创建代理对象。 对象注入到容器中
- @Param : 放在dao接口的方法的形参前面, 作为命名参数使用的。
6、Dubbo注解
- @DubboService: 在提供者端使用的,暴露服务的, 放在接口的实现类上面
- @DubboReference: 在消费者端使用的, 引用远程服务, 放在属性上面使用。
- @EnableDubbo : 放在主类上面, 表示当前引用启用Dubbo功能。
|