Spring Boot实战派----Spring Boot入门

Starter--开箱即用

Spring Boot为了简化配置,提供了非常多的starter,实现了开箱即用。

它先打包好与常用模块相关的所有JAR包,并完成自动配置,然后组装成Starter。这使得在开发业务代码时不需要过多关注框架配置,只需要关注业务逻辑即可。

通过在pom.xml添加依赖之后,使用@Autowired引入,即可使用。

URI与URL

URI(Universal Resource Identifier):统一资源标识符

URL():统一资源定位符

控制器

在Spring MVC中,控制器负责处理由DispatcherServlet接收并分发过来的请求。它把用户请求的数据通过业务处理层封装成一个Model,然后把Model返回给对应的View进行展示。

处理HTTP请求的方法

GET:获取资源

DELETE:删除资源,要判断是否成功

POST:提交资源

PUT:更新资源

PATCH:局部更新资源,比如更新一条数据的一个字段。

在方法中使用参数

//获取路径中的值,(http://localhost/article/123)
@GetMapping("article/{id}")
public ModelAndView getArticle(@PathVariable("id") Integer id){
//..........
}

//获取路径中的参数(http://localhost/user/?username=www)
@RequestMapping("/addUser")
public String addUser(String username){
//..........
}

//通过Bean接收HTTP提交的对象
public String addUser(UserModel user)

//用注解@ModelAttribute获取参数
@RequestMapping(value="addUser", method=RequestMethod.POST)
public String addUser(@ModelAttribute("user") UserModel user)

//通过HttpServletRequest接收参数
@RequestMapping("/addUser")
public String addUser(HttpServletRequest request){
    request.GETParameter("username");
}

//用@RequestParam绑定入参
@RequestParam(value="username", required=false)

//用@RequestBody接收JSON数据
@RequestMapping(value="addUser",method={RequestMethod.POST})
@ResponseBody
public void saveUser(@RequestBody List<User> users){
    
}


//上传文件MultipartFile
public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes){
    
}


//上传图片
@PostMapping("/upload")
@ResponseBody
public Map<String,Object> singleFileUpload(@RequestParam("upload") MultipartFile file,RedirectAttributes redirectAttributes){

}

响应式编程Webflux

与Spring MVC不同,WebFlux不需要Servlet API,完全异步无阻塞,并且通过Reactor项目实现Reactive  Streams规范。

可以在有限资源的情况下提高系统吞吐量和伸缩性(不是提高性能)。这意味着在资源相同的情况下,WebFlux可以处理更多的请求(不是业务)。

WebFlux除支持RESTful Web服务之外,还可以用于提供动态HTML内容。

WebFlux可以立即响应,返回数据与函数的组合(Mono或者Flux,不是结果),然后将收到的请求转发给Work线程去处理。WebFlux只会对Work线程形成阻塞,如果再来请求也可以处理。

Mono和Flux

是Reactor中的两个概念,都属于事件发布者,当有事件发生时,Mono或Flux会回调消费者的相应方法,然后通知消费者相应的事件。

用于处理异步数据流,将异步数据流包装成Mono或者Flux对象。

Mono返回单个数据,Flux返回多个数据。

注解式开发WebFlux

package com.testboot.testx.controller;

import com.testboot.testx.webflux.entity.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
public class UserController {
    Map<Long, User> users = new HashMap<>();

    @PostConstruct
    public void init() throws Exception{
        users.put(Long.valueOf(1), new User(1,"lzh",28));
        users.put(Long.valueOf(2), new User(2,"lzr",2));

    }

    @GetMapping("/list")
    public Flux<User> getAll(){
        return Flux.fromIterable(users.entrySet().stream()
                .map(entry -> entry.getValue())
                .collect(Collectors.toList()));
    }

    @GetMapping("/{id}")
    public Mono<User> getUser(@PathVariable Long id){
        return Mono.justOrEmpty(users.get(id));
    }

    @PostMapping("")
    public Mono<ResponseEntity<String>> addUser(User user){
        users.put(user.getId(), user);
        return Mono.just(new ResponseEntity<>("tjcg", HttpStatus.CREATED));
    }

    @PutMapping("/{id}")
    public Mono<ResponseEntity<User>> putUser(@PathVariable Long id, User user){
        user.setId(id);
        users.put(id, user);

        return Mono.just(new ResponseEntity<>(user, HttpStatus.CREATED));
    }
}

响应式开发WebFlux

(书中的代码失效,估计是版本的事)

Spring AOP

AOP,面向切面编程,把业务功能分为核心,非核心两部分。

核心业务功能:用户登录,增加数据,删除数据。

非核心业务功能:性能统计,日志,事务管理。

AOP将非核心业务功能定义为切面。核心业务功能和切面功能先被分别进行独立开发,然后再把切面功能和核心业务功能编织在一起。

AOP将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,以减少系统的重复代码,降低模块间的耦合度,利于未来的扩展和维护。

切入点:在哪些类,哪些方法上切入。

通知:在方法前,方法后,方法前后做什么。

切面:切面=切入点+通知。即在什么时机,什么地方,做什么。

织入:把切面加入对象,并创建出代理对象的过程。

环绕通知:AOP中最强大,灵活的通知,它集成了前置和后置通知,保留了连接点原有的方法。

package com.testboot.testx.log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class AopLog {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * com.testboot..*.*(..))")
    public void aopWebLog(){

    }

    @Before("aopWebLog()")
    public void doBefore(JoinPoint joinPoint){
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        System.out.println("URL:" + request.getRequestURL().toString());
        logger.info("URL:" + request.getRequestURL().toString());
        logger.info("Http方法:" + request.getMethod());
        logger.info("IP地址:" + request.getRemoteAddr());
        logger.info("类的方法:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("参数:" + request.getQueryString());

    }

    @AfterReturning(pointcut = "aopWebLog()", returning = "retObject")
    public void doAfterReturning(Object retObject) throws Throwable{
        System.out.println("应答值:" + retObject);
        logger.info("应答值:" + retObject);
        logger.info("费时:" + (System.currentTimeMillis() - startTime.get()));
    }

    @AfterThrowing(pointcut = "aopWebLog()", throwing = "ex")
    public void addAfterThrowingLogger(JoinPoint joinPoint,Exception ex) throws Throwable{
        System.out.println("执行"  + "异常"+ex);
        logger.error("执行"  + "异常",ex);
    }


}

Aspect注解声明其为切面类

Component注解将切面类加入IoC容器

Pointcut定义切点

IoC容器和Servlet容器

IoC容器,控制反转。它将程序中创建对象的控制权交给Spring框架来管理,以便降低耦合度。

IoC实现方式之一:依赖注入。由IoC在运行期间动态地将某种依赖关系注入对象之中。

IoC容器在主对象中设置Setter方法,通过调用Setter方法或构造方法传入所需引用(即依赖注入)。要使用某个对象,只需要从IoC中获取需要使用的对象,不需要关心对象创建过程,即把程序中创建对象的控制权交给Spring框架来管理。

IoC的实现方法:依赖注入,依赖查找。

依赖注入:IoC容器通过类型或名称等信息将不同对象注入不同属性中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

依赖查找:使用API来管理依赖创建,查找资源和组装对象。

Servlet容器

可以实现拦截与监听。

用IoC管理Bean

package com.testboot.testx.bean;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private int id;
    private String name;
}


package com.testboot.testx.config;

import com.testboot.testx.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {
    @Bean("user1")
    public User user(){
        User user = new User();
        user.setId(1);
        user.setName("dsd");
        return  user;
    }
}


package com.testboot.testx.test;

import com.testboot.testx.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
public class IoCTest {
    @Autowired
    private ApplicationContext applicationContext;

    @Test
    public void testIoC(){
        User user = (User) applicationContext.getBean("user1");
        System.out.println(user);
    }
}

Servlet

package com.testboot.testx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//ServletDemo02下的所有子路径
@WebServlet("/ServletDemo02/*")
public class ServletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().print("Servlet ServletDemo02");

    }
}


package com.testboot.testx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
public class TestxApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestxApplication.class, args);
	}

}

过滤器和监听器

过滤器:在数据传输时剔除我们不想要的数据,使用fliter来处理,额外的优点是省去了重复代码。

1 新建类继承Filter抽象类(javax.servlet.annotation.WebFilter;)(这里的WebFilter注解中的urlPattern,代表经过哪些路径时会进行过滤)

2 重写 init,doFilter,destroy

3 添加注解@ServletComponentScan

监听器:用于监听Web应用程序中某些对象或信息的创建,销毁,增加等,然后做出相应的处理。

ServletContextListener – 监听servletContext对象的创建以及销毁

HttpSessionListener – 监听session对象的创建以及销毁

ServletRequestListener – 监听servletRequest对象的创建以及销毁

ServletContextAttributeListener – 监听servletContext对象中属性的改变

HttpSessionAttributeListener --监听session对象中属性的改变

ServletRequestAttributeListener --监听request对象中属性的改变

HttpSessionBindingListener --监听HttpSession,并绑定以及解除锁定

HttpSessionActivationListener --监听钝化和活动的HttpSession状态改变

也需要@ServletComponentScan

package com.testboot.testx.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class listenerDemo02 implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext chushihua");
        System.out.println(sce.getServletContext().getServerInfo());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext xiaohui");
    }
}

自动配置原理

注解EnableAutoConfiguration借助注解@Import,将所有符合自动配置条件的Bean都加载到IoC容器中,

@EnableAutoConfiguration借助导入AutoConfigurationImportSelector.class,调用SpringFactoriesLoader的loadFactoryNames方法,从classpath中寻找所有的META-INF/spring.factories配置文件,再借助AutoConfigurationImportSelector,将所有符合条件的@Configuration配置都加载到IoC中。

SpringFactoriesLoader类从classpath中寻找所有的META-INF/spring.factories配置文件。

元注解

@Target(告诉Java将自定义注解放在什么地方,修饰什么内容)

@Retention(自定义注解生命周期)

@Inherited(表明被标记的类型可以被继承)

@Documented(是否将注解信息添加在Java文档)

@interface(声明一个注解)

package com.testboot.testx.aop;

import com.testboot.testx.annotation.MyTestAnnotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class TestAnnotationAspect {
    @Pointcut("@annotation(com.testboot.testx.annotation.MyTestAnnotation)")
    public void myAnnotationPointCut(){

    }

    @Before("myAnnotationPointCut()")
    public void before(JoinPoint joinPoint) throws Throwable{
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        MyTestAnnotation annotation = method.getAnnotation(MyTestAnnotation.class);
        System.out.println("TestAnno canshu: " + annotation.value());

    }
}


package com.testboot.testx.annotation;

import org.springframework.stereotype.Component;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface MyTestAnnotation {
    String value();

}

异常

spring使用控制器通知,使用切面技术来实现

(@ControllerAdvice(可以声明限定方式,比如注解,包名,类型)和@RestcontrollerAdvice)

package com.testboot.testx.exception;

public class BusinessException extends RuntimeException {

    private Integer code;

    public BusinessException(int code, String msg){
        super(msg);
        this.code = code;
    }
    public Integer getCode(){
        return code;
    }
    public void setCode(Integer code){
        this.code = code;
    }


}

package com.testboot.testx.controller;

import com.testboot.testx.exception.BusinessException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @RequestMapping("/BussinessException")
    public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
        if(i == 0){
            throw  new BusinessException(600, "elns");
        }
        return "succ";
    }
}

ORM

将数据库中的表和内存中的对象建立起映射关系,主要包括JPA和Mybatis,

JPA是一个规范化接口,封装了Hibernate的操作作为默认实现。

RESTFUL API

Spring Security

提供了声明式的安全访问控制解决方案。基于spring aop 和 servlet。

Spring Security 有三个核心概念。

Principle:用户的对象,可以用于验证的设备。

Authority:用户的角色,比如管理员或者会员。

Permission:权限。

验证步骤:

用户名密码登录。

过滤器获取用户名,密码,然后封装成Authentication

AuthenticationManager认证token

AuthenticationManager认证成功,返回一个封装了用户权限信息的Authentication对象等。

Authentication对象赋值给当前的SecurityContext,建立用户的安全上下文。

用户在进行一些涉及到安全的操作的时候,访问控制器会根据安全上下文来进行判断。

Spring Cache

Redis:分布式Session,高并发读写,计数器,排行榜。

RabbitMQ

消息延迟:订单,支付过期定时取消。

交换机:交换机将消息路由到一个或多个Queue中,或丢弃。

交换机(Exchange)有四种类型:direct,topic,fanout,headers

绑定:binding key,routing key

6种工作模式:简单模式,工作队列模式,交换机模式,Routing转发模式,主题转发模式,RPC模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值