springboot
1. Javaconfig
@Configuration:放在类的上面, 这个类相当于 xml 配置文件,可以在其中声明 bean
@Bean:放在方法的上面, 方法的返回值是对象类型, 这个对象注入到 spring ioc 容器
@ImportResource 是导入 xml 配置,等同于 xml 文件的 resources
@PropertyResource 是读取 properties 属性配置文件
2. spring boot入门
2.1 基本注解
@SpringBootApplication : @SpringBootApplication 是 一 个 复 合 注 解 , 是 由
@SpringBootConfiguration, @EnableAutoConfiguration ,@ComponentScan 联合在一起组
成的。
@SpringBootConfiguration : 就 是 @Configuration 这 个 注 解 的 功 能 , 使 用
@SpringBootConfiguration 这个注解的类就是配置文件的作用。
@EnableAutoConfiguration:开启自动配置, 把一些对象加入到 spring 容器中。
@ComponentScan:组件扫描器, 扫描注解,根据注解的功能,创建 java bean,给属性赋值
等等。组件扫描器默认扫描的是 @ComponentScan 注解所在的类, 类所在的包和子包。
2.2 多环境
为每个环境创建一个配置文件,命名必须以 application-环境标识.properties|yml
application.properties(在这里指定使用的环境文件)
spring.profiles.active=test
2.3 注解
2.3.1 @Value
@Value(“${key}”) , key 来自 application.properties(yml)
application.properties
school.name=动力节点
school.address=北京大兴区
school.website=www.bjpowernode.com
读取配置文件数据
@Value("${server.port}")
private String port;
2.3.2 @ConfigurationProperties
将整个文件映射成一个对象,用于自定义配置项比较多的情况
创建 SchoolInfo 类,并为该 类加上Component 和 ConfigurationProperties 注解,prefix 可以不指定,如果不指定,那么会去配置文件中寻找与该类的属性名一致的配置,prefix 的作用可以区分同名配置
application.properties
school.name=动力节点
school.address=北京大兴区
school.website=www.bjpowernode.com
@Component
@ConfigurationProperties(prefix = "school")
public class SchoolInfo {
private String name;
private String address;
private String website;
// set | get 方法
}
@Resource
private SchoolInfo schoolInfo;
2.4 JSP
1.添加依赖
<!--如果只是使用 JSP 页面,可以只添加该依赖-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--如果要使用 servlet 必须添加该以下两个依赖-->
<!-- servlet 依赖的 jar 包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- jsp 依赖 jar 包-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!--如果使用 JSTL 必须添加该依赖-->
<!--jstl 标签依赖的 jar 包 start-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency
2.配置build
<resources>
<resource>
<!--源文件位置-->
<directory>src/main/webapp</directory>
<!--指定编译到META-INF/resource,该目录不能随便写-->
<targetPath>META-INF/resources</targetPath>
<!--指定要把哪些文件编译进去,**表示 webapp 目录及子
目录,*.*表示所有文件-->
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
3.配置springmvc
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
4.创建JspController 类
@Controller
public class SpringBootController {
@RequestMapping(value = "/springBoot/jsp")
public String jsp(Model model) {
model.addAttribute("data","SpringBoot 前端使用 JSP页面!");
return "index";
}
}
5.创建webapp
在该目录下新建index.jsp页面
6.jsp 中获取 Controller 传递过来的数据
3. springboot 和 web组件
3.1 拦截器
1.创建类实现 HandlerInterceptor 接口
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行了 LoginInterceptor,preHandle()");
return true;
}
}
2.注册拦截器
@Configuration
public class MyAppConfig implements WebMvcConfigurer {
//注册拦截器对象的
@Override
public void addInterceptors(InterceptorRegistry registry) {
// InterceptorRegistry 登记系统中可以使用的拦截器
// 指定拦截的地址
String path [] = {"/user/**"};
String excludePath [] = {"/user/login"};
registry.addInterceptor( new LoginInterceptor())
.addPathPatterns(path).excludePathPatterns(excludePath);
} }
3.创建测试controller
@Controller
public class BootController {
@RequestMapping("/user/account")
@ResponseBody
public String queryAccount(){
return "user/account";
}
@RequestMapping("/user/login")
@ResponseBody
public String login(){
return "/user/login";
} }
3.2 Servlet
1.创建Servlet
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();
}
}
2.注册Servlet
@Configuration
public class SystemConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean reg = new ServletRegistrationBean(
new MyServlet(),"/loginServlet");
return reg;
}
}
3.3 Filter
1.创建Filter对象
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException,
ServletException {
System.out.println("使用了 Servlet 中的 Filter 对象");
filterChain.doFilter(servletRequest,servletResponse);
}
}
2.注册Filter
@Configuration
public class SystemConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean reg = new FilterRegistrationBean();
//使用哪个过滤器
reg.setFilter( new MyFilter());
//过滤器的地址
reg.addUrlPatterns("/user/*");
return reg;
} }
3.创建Controller
@Controller
public class FilterController {
@RequestMapping("/user/account")
@ResponseBody
public String hello(){
return "/user/account";
}
@RequestMapping("/query")
@ResponseBody
public String doSome(){
return "/query";
}
}
3.4 字符集过滤器
application.properties 文件中设置过滤器
Spring Boot 项目默认启用了 CharacterEncodingFilter, 设置他的属性就可以
#设置 spring boot 中 CharacterEncodingFitler 的属性值
server.servlet.encoding.enabled=true
server.servlet.encoding.charset=utf-8
#强制 request, response 使用 charset 他的值 utf-8
server.servlet.encoding.force=true
4. MySQL
4.1 过程
1.配置
<!--mybatis 起步依赖: mybatis 框架需要的依赖全部加入好-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--mysql 驱动-->
<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>
<!--加入 resource 插件--> <resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
2.配置数据源
#连接数据库
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
#serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123
4.2 @MapperScan
在 Dao 接口上面加入@Mapper,需要在每个接口都加入注解。
当 Dao 接口多的时候不方便。可以使用如下的方式解决。主类上添加注解包扫描:@MapperScan(“com.bjpowernode.dao”)
4.3 mapper文件和java代码分开管理
这种方式比较推荐,mapper 文件放在 resources 目录下, java 代码放在 src/main/java。
在 application.properties 配置文件中指定映射文件的位置,这个配置只有接口和映
射文件不在同一个包的情况下,才需要指定。
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4.4 事务支持
➢ 在入口类中使用注解 @EnableTransactionManagement 开启事务支持
➢ 在访问数据库的 Service 方法上添加注解 @Transactional 即可
5. RESTful-接口架构风格
5.1 注解
5.1.1 @PathVariable
获取 url 中的数据
属性: value : 路径变量名称
位置: 在逐个接收参数中,在形参定义的前面
注意:路径变量名和形参名一样, value 可以不写
5.1.2 @PostMapping
接收和处理 Post 方式的请求
5.1.3 @DeleteMapping
接收 delete 方式的请求,可以使用 GetMapping 代替
5.1.4 @PutMapping
接收 put 方式的请求,可以用 PostMapping 代替
5.1.5 @GetMapping
接收 get 方式的请求
5.2 演示
@GetMapping(value = "/student/{studentId}/{classname}")
public String queryStudent(
@PathVariable(value = "studentId") Integer id,
@PathVariable String classname){
return "get 请求,查询学生 studentId:"+id+", 班级:"+classname;
}
///student/1001/bjpowernode
@GetMapping(value = "/student/{studentId}/school/{schoolname}")
public String queryStudentBySchool(@PathVariable(value = "studentId")
Integer id,
@PathVariable String schoolname){
return "get 请求,查询学生 studentId:"+id+", 班级:"+schoolname;
}
@PostMapping("/student/{stuId}")
public String createStudent(@PathVariable("stuId") Integer id,
String name,
Integer age){
return "post 创建学生, id="+id+",name="+name+",age="+age;
}
@PutMapping("/student/{stuId}")
public String modifyStudent(@PathVariable("stuId") Integer id,
String name){
System.out.println("===========put 请求方式 ========");
return "put 修改学生, id="+id+",修改的名称是:"+name;
}
@DeleteMapping("/student/{stuId}")
public String removeStudent(@PathVariable("stuId") Integer id){
System.out.println("===========delete 请求方式 ========");
return "delete 删除学生,id="+id;
}
}
application.properties 文件
server.servlet.context-path=/myboot
启用 HiddenHttpMethodFilter 这个过滤器, 支持 post 请求转为 put,delete
spring.mvc.hiddenmethod.filter.enabled=true
设计路径,必须唯一, 路径 uri 和 请求方式必须唯一。
6. 集成Redis
Redis 是一个 NoSQL 数据库, 常作用缓存 Cache 使用。 通过 Redis 客户端可以使用多种
语言在程序中,访问 Redis 数据。java 语言中使用的客户端库有 Jedis,lettuce, Redisson
等。
Spring Boot 中使用 RedisTemplate 模版类操作 Redis 数据。
需求:完善根据学生 id 查询学生的功能,先从 redis 缓存中查找,如果找不到,再从数
据库中查找,然后放到 redis 缓存中
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.核心配置文件 application.properties
#指定 redis
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=123456
3.创建 RedisController
@RestController
public class RedisController {
//注入 RedisTemplate
//泛型 key,value 都是 String ,或者 Object, 不写
@Resource
private RedisTemplate redisTemplate;
@GetMapping("/myname")
public String getName(){
redisTemplate.setKeySerializer( new StringRedisSerializer());
// redisTemplate.setValueSerializer( new StringRedisSerializer());
String name=(String) redisTemplate.opsForValue().get("name");
return name;
}
@PostMapping("/name/{myname}")
public String addName(@PathVariable("myname") String name){
redisTemplate.opsForValue().set("name",name);
return "添加了学生:"+name;
} }
4.启动redis服务
7. 集成Dubbo
7.1 创建接口module
01:普通maven项目
1.model类
public class Student implements Serializable {
private Integer id;
private String name;
private Integer age;
//set|get 方法
}
2.服务接口
public interface StudentService {
Student queryStudent(Integer studentId);
}
7.2 服务提供者module
02:springboot 无依赖
1.添加依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
</dependency
2.application.properties
#服务名称
spring.application.name=service-provider
#zookeeper 注册中心
dubbo.registry.address=zookeeper://localhost:2181
#dubbo 注解所在的包名
dubbo.scan.base-packages=com.bjpowernode.service
3.创建接口实现类
@Component
@DubboService(interfaceClass = StudentService.class,version = "1.0")
public class StudentServiceImpl implements StudentService {
@Override
public Student queryStudent(Integer studentId) {
Student student = new Student();
student.setId(studentId);
student.setName("张三");
student.setAge(20);
return student;
}
}
4.主启动类上加@EnableDubbo
7.3 创建消费者module
03:springboot web依赖
1.添加依赖
<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>
</dependency>
2.application.properties
#服务名称
spring.application.name=service-consumer
#dubbo 注解所在的包
dubbo.scan.base-packages=com.bjpowernode
#zookeeper
dubbo.registry.address=zookeeper://localhost:2181
3.创建MyController
@RestController
public class MyController {
@DubboReference(interfaceClass = StudentService.class,version =
"1.0",check = false)
private StudentService studentService;
@GetMapping("/query")
public String searchStudent(Integer id){
Student student = studentService.queryStudent(id);
return "查询学生:"+ student.toString();
}
}
4.主启动类上加@EnableDubbo
7.4 测试
1)先启动 zookeeper
2)运行服务提供者 02-service-provider
3)运行消费者 03-consumer
4)在浏览器执行 http://localhost:8080/query?id=1
日志依赖 SLF4j 多次加入了。只需要依赖一次就可以。
解决方式:排除多余的 SLF4j 依赖, 提供者和消费者项目都需要这样做
<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>