Spring
Spring 是一个框架
Spring 注解开发

SpringConfig.java 【代替原先 XML】
1 2 3 4
| @Configuration @ComponentScan("com.xekoner") public class SpringConfig { }
|
@Configuration 注解用于设定当前类为配置类
@ComponentScan("com.xekoner") 注解用于设定扫描路径,此注解只能添加一次; 多个需要使用数组格式: @ComponentScan({"",""})
UserDao.java
1 2 3 4 5 6
| @Repository public class UserDao { public void save(){ System.out.println(">>> UserDao.save"); } }
|
App.java
1 2 3 4 5 6 7 8 9
| public class App { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); UserDao userDao = ctx.getBean(UserDao.class); userDao.save(); } }
|
依赖注入
UserServices.java
1 2 3 4 5 6 7 8 9
| @Service public class UserServices { @Autowired private UserDao userDao; public void doThis(){ System.out.println(">>> UserDao.Do!"); userDao.save(); } }
|
随后修改主函数 App.java 的代码逻辑,不去找 UserDao,直接去找 UserServices
1 2 3 4 5 6 7 8
| public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); UserServices userServices = ctx.getBean(UserServices.class); userServices.doThis(); }
|
AOP
面向切面编程,一种编程思想
在不惊动原始设计的基础上为其进行功能增强 (无入侵式)
公用的代码可以提取出来,组成通知类;这个方法叫通知
每一个方法都可以去调用通知类,这叫做连接点
需要执行这个通知的方法找出来定义成切入点
切入点到通知,这叫做切面
案例:
导入坐标
pom.xml
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.1.3</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
|
在 UserDao 中设定一个切入点:

UserServices 调用了 UserDao 中的 demo 方法
1 2 3 4 5 6 7 8 9
| @Service public class UserServices { @Autowired private UserDao userDao; public void doThis(){ System.out.println(">>> UserDao.Do!"); userDao.demo(); } }
|
最后以 App 主函数调用 Services 的 doThis 方法【逻辑不变】
1 2 3 4 5
| public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); UserServices userServices = ctx.getBean(UserServices.class); userServices.doThis(); }
|
切入点想好了之后接下来开始写切面代码:
1 2 3 4 5 6 7 8 9 10 11 12
| @Component @Aspect @EnableAspectJAutoProxy public class AdviceDemo { @Pointcut("execution(void com.xekoner.UserDao.demo())") private void pt(){} @Before("pt()") public void method(){ System.out.println(System.currentTimeMillis()); } }
|
其中 pt() 仅仅是引用作用,无实际意义
可以看到先运行了 UserServices 中的 doThis 方法
然后切入点运行通知
最后运行 demo 方法
如果在 Services 中把 userDao.demo(); 改为 userDao.save()
那就没有找到切入点也不会去调用通知方法

切入点表达式
execution(<public / private> <返回值> <包名><接口名><方法名> <参数>)
比如: execution(void com.xekoner.UserDao.demo())
可以使用 * 匹配任意符号
1 2 3 4
| execution(public * com.xekoner.*.UserService.find* (*)) execution(public com.*.*.*.update()) execution(public *..update()) execution(* *..*(..)) 任意的任意的任意的任意(不用仅参考)
|
Spring MVC
和 Servlet功能等同, 基于JAVA实现的MVC模型的轻量级Web框架
初始案例
导入pom坐标
注意 servlet与tomcat会有冲突,需要指定范围为 provided
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency>
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
|
编写控制类
UserController.java (位于 main.java.con.xekoner.controller)
1 2 3 4 5 6 7 8 9
| @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(){ System.out.println("User Save ... "); return "{'module':'springmvc'}"; } }
|
编写配置类
main.java.com.xekoner.config.SpringMvcConfig
1 2 3 4
| @Configuration @ComponentScan("com.xekoner.controller") public class SpringMvcConfig { }
|
创建一个容器类
main.java.com.xekoner.config.ServletContainerInitConfig
注意是创建 AnnotationConfigWebApplicationContext 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer { @Override protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMvcConfig.class); return ctx; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } @Override protected WebApplicationContext createRootApplicationContext() { return null; } }
|
传递 List为(Json):
需要添加 jackson 坐标
pom.xml
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.19.2</version> </dependency>
|
为 Controller添加一个方法
1 2 3 4 5 6
| @RequestMapping("/listParamForJson") @ResponseBody public String listParamForJson(@RequestBody List<String> likes){ System.out.println("Json >>> " + likes); return "{'module':'listParamForJson'}"; }
|
同时需要在配置中添加
1 2 3 4 5
| @Configuration @ComponentScan("com.xekoner.controller") @EnableWebMvc public class SpringMvcConfig { }
|
1 2 3
| @DateTimeFormat(pattern="yyyy-MM-dd") @RequestBody @RequestParam("name")
|
REST规则开发
接口相同,调用方式不同导致不同的功能
1 2 3 4 5
| DELETE /users/1 删除user1 PUT /users 修改user1 POST /users 添加users GET /users 查询 GET /users 查询
|
从原先的 @RequestMapping("/save") 改为
1
| @RequestMapping(value = "/users",method = RequestMethod.POST)
|
访问 curl -s -X POST "http://localhost:8080/SpringMVC_war_exploded/users/" 回显
1 2 3 4 5 6
| @RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable Integer id){ System.out.println(">> delete " + id); return "delete"; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Controller public class UserController { @RequestMapping(value = "/users",method = RequestMethod.POST) @ResponseBody public String save(){ System.out.println(">> Save ..."); return "save"; } @RequestMapping(value = "/users/{id}",method = RequestMethod.GET) @ResponseBody public String query(@PathVariable Integer id){ System.out.println(">> query " + id); return "query"; } @RequestMapping(value = "/users",method = RequestMethod.GET) @ResponseBody public String query(){ System.out.println(">> query all "); return "query"; } @RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable Integer id){ System.out.println(">> delete " + id); return "delete"; } @RequestMapping(value = "/users/{id}",method = RequestMethod.PUT) @ResponseBody public String modify(@PathVariable Integer id){ System.out.println(">> modify " + id); return "modify"; } }
|
Tips:
相同的路径可以写在最前面
1 2 3 4
| @RequestMapping("/users")
... @RequestMapping(value = "/{id}",method = RequestMethod.GET)
|
因为所有方法中都带有 @ResponseBody , 所以可以和@Controller 一起省略成:
方法前的注解也可以省略写
1 2 3 4 5 6
| @RequestMapping(method = RequestMethod.POST)
@PostMapping
@GetMapping("/{id}")
|
拦截器
拦截器和过滤器的区别
拦截器为SpringMVC技术,过滤器为Servlet技术
拦截器仅对SpringMVC访问进行增强,而过滤器是对所有访问加强
- Example
PorjectInterception.java , Location: com.xekoner.cotroller.Interception.PorjectInterception.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Component public class PorjectInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { System.out.println("afterCompletion"); } }
|
同时修改配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration @ComponentScan("com.xekoner.controller") @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private PorjectInterceptor porjectInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(porjectInterceptor).addPathPatterns("/users","/users/*"); } }
|
1 2 3
| Pre1 -> Pre2 -> Pre3 -> Controller -> Post3 -> Post3 -> Post1 -> After3 -> After2 -> After1
|
SpringBoot
简化spring应用的搭建以及开发过程
Project Create

Dependencies 选择 Web中的 Spring Web
检查pom是否有
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
- Demo
BookController.java ; Location: main.java.com.xekoner.springboot.controller.BookController.java
1 2 3 4 5 6 7 8 9 10
| @RestController @RequestMapping("/books") public class BookController { @GetMapping("/{id}") public String getBooks(@PathVariable Integer id){ System.out.println(">>> Get Books: " + id); return "hello , springboot!"; } }
|
然后直接右键Application,Run即可。
- 打包操作

boot配置文件
Default Location : resources -> application.properties
或者 application.yml / application.yaml