2024-05-08 17:12阅读: 15评论: 0推荐: 0

spring刷题记录——to be continue

  在牛客网刷的题目,类似于补基础了?

  这里按照知识点进行分类,因为发现有些同样的知识点不同的题目还是很痛苦。

  这里就不用颜色标记了,因为我觉得都要记。

 

  Spring和Springboot补充内容:

    (来自牛客网用户谦虚的花生米)
    A自动配置是Spring Boot的核心功能之一,它能够根据应用程序的依赖和配置自动配置Spring应用程序的各种组件和功能。
    B起步依赖也是Spring Boot的核心功能之一,它能够简化项目的构建和依赖管理,通过引入特定的起步依赖,可以轻松地集成各种常用的框架和库。
    DIoC(依赖注入和控制反转)和AOP(面向切面编程)是Spring框架的核心功能,Spring Boot作为Spring框架的扩展,继承了这些核心功能。DIoC和AOP能够帮助开发者实现松耦合、可维护和可扩展的应用程序。
    C端点监控不属于Spring Boot的核心功能。端点监控是Spring Boot Actuator提供的功能之一,它能够暴露应用程序的各种管理和监控端点,用于监控应用程序的运行状态和性能指标。虽然端点监控是Spring Boot常用的功能之一,但它不属于Spring Boot的核心功能。

    
可以快速构建项目。项目可独立运行,无需外部依赖Servlet容器。提供运行时的应用监控。可以极大地提高开发、部署效率。

 

 Spring容器篇

    Spring容器也叫做Ioc容器(Ioc,在我之前写的随笔里面也有谈到),本质上就是一个工厂。

    IoC是控制反转的意思,是一种面向对象编程的设计思想。在不采用这种思想的情况下,我们需要自己维护对象与对象之间的依赖关系,很容易造成对象之间的耦合度过高,在一个大型的项目中这十分的不利于代码的维护。IoC则可以解决这种问题,它可以帮我们维护对象与对象之间的依赖关系,并且降低对象之间的耦合度。

    Spring提供了众多容器类,最常用的有BeanFactory和ApplicationContext。

    BeanFactory是所有Spring Bean的容器根接口,其给IoC容器提供了一套完整的规范。FactoryBean是 一种创建Bean的方式,是对Bean的一种扩展。

    Spring容器不仅可以管理Bean,还能管理Bean的生命周期、作用域。

    (放链接时想要大家都可以去看,作为记录这里只是写一些简短内容,链接通常会有更加复杂的内容。)

    一文读懂 Spring Bean 的生命周期_spring bean的生命周期-CSDN博客

      Bean的生命周期:

    •   实例化 Instantiation
    •   属性赋值 Populate
    •   初始化 Initialization
    •   销毁 Destruction

      具体的代码:

复制代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }

    if (instanceWrapper == null) {
        // 实例化阶段
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

    ...

    Object exposedObject = bean;

    try {
        // 属性赋值阶段
        this.populateBean(beanName, mbd, instanceWrapper);
        // 初始化阶段
        exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable var18) {
        ...
    }

    ...
}
复制代码

      Bean的作用域:

        singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。(SpringBean的默认作用范围)
        prototype : 每次请求都会创建一个新的 bean 实例。
        request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
        session : 创建scope为session的bean实例,该bean仅在当前 HTTP session 内有效。同一个会话中的多个请求可以复用scope为session的bean实例,不一定每个请求都新建一个该实例,避免浪费。

        global-session: 全局 session 作用域,仅仅在基于 Portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。


    Spring容器一般是自动创建的,一个类实现ApplicationContextAware接口,重写setApplicationContext方法就可以获取到ApplicationContext对象。

    Spring容器的顶层接口时BeanFactory,而常用的接口是ApplicationContext。

    在BeanFactory定义方法中,getBean(String name)方法是从Spring容器中获取对应Bean对象的方法,如存在,则返回该对象。containsBean(String name)方法用于判断Spring容器中是否存在该对象。isSingleton(String name)方法用于判断Bean对象是否为单例对象。而getBean用来获取Bean的Class类型。

    bean的注入有3种方式。1.属性注入、2构造器注入、3接口注入。bean的创建方式。有构造器创建、实例工厂创建、静态工厂创建。(注入是set方法)

(注入可以理解成属性的注入)  

  1.    属性注入:通过在Bean类中定义对应的属性,并使用注解或XML配置文件将属性值注入到Bean中。可以使用@Autowired、@Value等注解进行属性注入。

  2. 构造器注入:通过在Bean类中定义对应的构造器,并使用注解或XML配置文件将构造器参数注入到Bean中。可以使用@Autowired、@Qualifier等注解进行构造器注入。

  3. 接口注入:通过在Bean类中实现对应的接口,并使用注解或XML配置文件将接口的实现类注入到Bean中。可以使用@Autowired、@Qualifier等注解进行接口注入。

关于Bean的创建方式:

  1. 构造器创建:通过调用Bean类的构造器来创建Bean实例。可以使用默认构造器或带参数的构造器来创建Bean实例。

  2. 实例工厂创建:通过定义一个工厂类,工厂类中包含创建Bean实例的方法,并在XML配置文件中配置工厂类和方法的信息,通过工厂类的方法来创建Bean实例。

  3. 静态工厂创建:通过定义一个静态工厂类,工厂类中包含创建Bean实例的静态方法,并在XML配置文件中配置工厂类和方法的信息,通过静态工厂类的方法来创建Bean实例。

 

    (这真的会有人记得住啊???)

    SpringApplication调用的run方法执行流程如下:

      1. 初始化监听器,以及添加到SpringApplication的自定义监听器。

      2. 发布ApplicationStartedEvent事件,如果想监听ApplicationStartedEvent事件,你可以这样定义:public class ApplicationStartedListener implements ApplicationListener,然后通过SpringApplication.addListener(..)添加进去即可。

      3. 装配参数和环境,确定是web环境还是非web环境。

      4. 装配完环境后,就触发ApplicationEnvironmentPreparedEvent事件。

      5. 如果SpringApplication的showBanner属性被设置为true,则打印启动的Banner。

      6. 创建ApplicationContext,会根据是否是web环境,来决定创建什么类型的ApplicationContext。

      7. 装配Context的环境变量,注册Initializers、beanNameGenerator等。

      8. 发布ApplicationPreparedEvent事件。

      9. 注册springApplicationArguments、springBootBanner,加载资源等

      10. 遍历调用所有SpringApplicationRunListener的contextLoaded()方法。

      11. 调用ApplicationContext的refresh()方法,装配context beanfactory等非常重要的核心组件。

      12. 查找当前ApplicationContext中是否注册有CommandLineRunner,如果有,则遍历执行它们。

      13. 发布ApplicationReadyEvent事件,启动完毕,表示服务已经可以开始正常提供服务了。通常我们这里会监听这个事件来打印一些监控性质的日志,表示应用正常启动了。      

      所以该方法作用包括:获取监听器参数配置,打印Banner信息, 监听器发送通知,创建并初始化容器

  

 SpringAOP篇:

    (来自于牛客网用户Mr丶PYK)

    aop的五类通知: 前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。

    正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。

    异常返回通知[After throwing advice]:在连接点抛出异常后执行。

    返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。

    环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
    环绕通知可以决定目标方法的调用也可以控制返回对象。

    (以下定义太抽象了,最好结合对应的AOP实例来看,我还没有写,所以这里只能Spring AOP 详细深入讲解+代码示例-阿里云开发者社区 (aliyun.com),写得很详实)

    切点:定义要拦截的bean

    连接点:定义要拦截的bean的哪个方法

      Aspect:切面,由一系列切点、增强和引入组成的模块对象,可定义优先级,从而影响增强和引入的执行顺序。事务管理(Transaction management)在java企业应用中就是一个很好的切面样例。所以他不是一个被代理的对象。

     Join point:接入点,程序执行期的一个点,例如方法执行、类初始化、异常处理。 在Spring AOP中,接入点始终表示方法执行。
    Advice:增强,切面在特定接入点的执行动作,包括 “around,” “before” and "after"等多种类型。包含Spring在内的许多AOP框架,通常会使用拦截器来实现增强,围绕着接入点维护着一个拦截器链。
    Pointcut:切点,用来匹配特定接入点的谓词(表达式),增强将会与切点表达式产生关联,并运行在任何切点匹配到的接入点上。通过切点表达式匹配接入点是AOP的核心,Spring默认使用AspectJ的切点表达式。
    Introduction:引入,为某个type声明额外的方法和字段。Spring AOP允许你引入任何接口以及它的默认实现到被增强对象上。
    Target object:目标对象,被一个或多个切面增强的对象。也叫作被增强对象。既然Spring AOP使用运行时代理(runtime proxies),那么目标对象就总是代理对象。
    AOP proxy:AOP代理,为了实现切面功能一个对象会被AOP框架创建出来。在Spring框架中AOP代理的默认方式是:有接口,就使用基于接口的JDK动态代理,否则使用基于类的CGLIB动态代理。但是我们可以通过设置proxy-target-class="true",完全使用CGLIB动态代理。
    Weaving:织入,将一个或多个切面与类或对象链接在一起创建一个被增强对象。织入能发生在编译时 (compile time )(使用AspectJ编译器),加载时(load time),或运行时(runtime) 。Spring AOP默认就是运行时织入,可以通过枚举AdviceMode来设置。
    织入,就是将方面组件中定义的横切逻辑,织入到目标对象的连接点的过程。
    可以在编译时织入,需要使用特殊的编译器。
    可以在装载类时织入,需要使用特殊的类装载器。
    可以在运行时织入,需要为目标生成代理对象。
 
    (以下来自于牛客网用户   hwx的offer快来)
    静态代理:也就是自己手动创建的代理对象
    动态代理:也就是在程序运行中通过配置参生的
    那么Spring的AOP也就是面向切面编程,就是基于动态代理来实现的,通过代理原始类增加额外功能,我们可以将额外功能一次定义然后配合切点达到多次使用的效果,比如 做日志啊 事物啊 时间啊等等…提高了复用性 开发效率.
    那么在Spirng当中动态代理有两种
    第一种也就是JDK自带的动态代理
    1.JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理.需要指定一个类加载器,然后生成的代理对象实现类的接口或类的类型,接着处理额外功能.JDK是基于接口
    第二只也就是Cglib的动态代理
    2.Cglib是动态代理利用asm的开源包,对代理对象的Class文件加载进来,通过修改其字节码生成的子类来处理
    Cglib是基于继承父类生成的代理类.
    在Spirng当中动态代理的使用
    1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理来实现AOP
    2.如果目标对象实现了接口,也可以强制使用CGlib来实现AOP
    3.如果目标对象没有实现接口,必须采用Cglib库,Spirng会自动在JDK和CGlib用切换
    如何强制使用CGlib来实现AOP?
    1.添加CGlibjar包:SPRING_HOME/cglib/*.jar
    2.在Spring的配置文件中加入 //默认是false 也就是用JDK的 改为true就是用Cglib的
    JDK和动态代理和CGlib字节码的生成区别?
    1.JDK动态代理制能对实现了接口的类生成代理,而不是针对类
    2.CGLIB是针对类实现代理,主要对指定的类生成一个子类,覆盖其中的方法,添加额外功能,因为是继承,所以该类方法不能用final来声明.




  Spring事务:

    Spring规定的7种类型的事务传播行为:   

     做题的时候记得看清楚(凝视)。

     spring事务隔离级别;

     幻读脏读什么的在隔壁的mysql刷题中也有提到。

     补充知识: 事务属性的种类:   传播行为、隔离级别、只读和事务超时。 

     

  

 

 Spring注解篇:

    (该篇主要是写一些注解的源码内容的)

     @RequestMapping注解的属性包括 method , value , params等。

     @Conditional是SpringMVC的注解,条件装配。

Spring @Conditional注解 详细讲解及示例_spring conditional-CSDN博客

     @Autowired注解,如果一个类有多种类型,那么容器注入时就会有困扰。此时可以使用@Primary和@Qualifier注解。

      (以下来自牛客网用户 李橙子)

      @Autowired
      注入声明的SpringBean对象,根据一定的规则首先按照注入的类型去查找,如果没有找到安装注入的名称去匹配你要注入的属性名称,如果都没有找到启动项目时抛出异常,@Autowired(required = false) 表示没有找到注入对象时,不抛异常,注入null。

     @Primary
      如果有多个相同类型的SpringBean,我们可以使用@Primary注解,优先注入带该注解标识的类,@Primary可以在多个类上标注,那就会抛异常。

     @Quelifier
      使用SpringBean的名称(SpringBean的名称都是唯一的)进行注入。

     以下是Spring MVC注解的讨论:

      begin:

      @ControllerAdvice用于定义控制器的通知类,它可以对指定的控制器进行增强。

      @InitBinder用于定义控制器参数绑定规则,如转换规则,它会在参数转换之前执行。

      @ModelAttribute用于定义控制器方法执行之前,对数据模型的操作。
      @ExceptionHandler用于定义控制器发生异常后的操作。

      @DateTimeFormat注解用于获取格式化的日期参数。

      @NumberFormat注解用于获取格式化的数字参数。

      @RequestBody注解用于从请求体中获取参数。

      A.@RequestMapping:
              映射URL路径,将http的请求地址映射到控制器(controller)类的处理方法上。可以定义在控制器类上,也可以定义在类里面的方法上。
      B.@RequestParam:
              把请求中的指定名称的参数传递给控制器中的形参赋值。
      C.@RequestBody:
              主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的),所以只能发送POST请求。当同时使用@RequestParam()和@RequestBody时,@RequestParam()指定的参数可以是普通元素、数组、集合、对象等等(即:当,@RequestBody 与@RequestParam()可以同时使用时,原SpringMVC接收参数的机制不变,只不过RequestBody 接收的是请求体里面的数据;而RequestParam接收的是key-value里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。@ResponseBody一般在异步获取数据时使用,但不代表它只能应用于异步请求之中。
      D.@PathVariable:
              将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过

      @PathVariable(“xxx”) 绑定到操作方法的入参中。如:

              URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx”) 绑定到操作方法的入参中。

     end;

     @PostContruct是给Bean初始化,@PreDestroy是销毁,这俩控制Bean生命周期

     @EnableAutoConfiguration注解,该注解结构如下:

     以上的总结成四句话:该注解由组合注解@SpringBootApplication引入。该注解作用是开启Spring Boot自动配置。该注解会扫描各个jar包下的spring.factories文件,并加载文件中注册的AutoConfiguration类等。@EnableAutoConfiguration的关键功能是通过@Import注解导入的ImportSelector来完成的。

    (补充知识:

    .class文件理解:详解.class文件-CSDN博客
      在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题并且保留了解释型语言可移植的特点,而通过即时编译器(jit)又有编译型语言执行效率高的特点。所以 Java 程序运行时比较高效。Java通过字节码文件和虚拟机jvm之间的关系,做到了平台无关性,一次编译,各平台都可运行。

      补充Clojure(Lisp 语言的一种方言)、Groovy、Scala 等语言都是运行在 Java 虚拟机之上。下图展示了不同的语言被不同的编译器编译成.class文件最终运行在 Java 虚拟机之上。
    )对于class我就是理解成了另一种形式的缓存文件。

    SpringBoot注解中,主要功能是启动Spring应用程序上下文时进行自动配置的注解是@EnableAutoConfiguration(原因如上)。

 

    @Autowired是Spring提供的注解,@Resource是JDK提供的注解。它们的区别是,@Autowired只能按类型注入,@Resource默认按名称注入,也支持按类型注入。

    @Autowired注解可以用于成员变量,方法,构造方法上。

    @Qualifier用于声明Bean的名称,可以引用默认名称,能引用Bean的自定义名称。(Bean注解可以指定名称,写了就是自定义名称,不写就是默认名称)

    @Bean注解可以用于装配任何Bean。@Bean注解作用在方法上,表示该方法的返回值将被装配到容器中。@Bean注解包含name属性,可以通过该属性指定装配的Bean的名称。@Bean注解通常出现在带有@Configuration注解的类中,但这不是必要的条件,它也可以出现在带有@Component注解的类中,甚至是普通的类中。

     

    @ComponentScan注解默认规则是对当前包及其子包中的Bean进行扫描。(包括了子包,题目可能会考)

    @ComponentScan注解用于定义Bean的扫描策略。   

    @ComponentScan注解的basePackages属性用于自定义要扫描哪些包。

    @ComponentScan注解只是定义了扫描范围,在此范围内带有特定注解的Bean才会被载入容器。

 

    @Transactional可以作用在类上,代表这个类的所有公共非静态方法都将启用事务。

      可以通过@Transactional的propagation属性,指定事务的传播行为。
      可以通过@Transactional的isolation属性,指定事务的隔离级别。
      可以通过@Transactional的rollbackFor属性,指定发生哪些异常时回滚。
 
    @RequestMapping注解的快捷方式,相当于固定了method配置项的值,包括:@GetMapping、@PostMapping、@PatchMapping、@PutMapping、@DeleteMapping。
 

 Spring MVC:

    在控制器的方法中,我们可以直接使用Request、Response对象处理请求与响应(有印象,是那个参数)

    ModelAndView对象,既可以存储模型数据,又可以存储模板路径。

    Model对象只能存放模型数据,对象可以被自动实例化。

    Spring MVC的核心组件是DispatcherServlet,负责分发所有的请求。

    View是视图的顶层接口(在做的时候脑子蒙蒙的,现在想起来就是这样子的)

    AbstractJackson2View不是逻辑视图,它不依赖ViewResolver的定位,直接将模型渲染为json。

    AbstractUrlBasedView是逻辑视图,它依赖ViewResolver定位模板,然后将模型传入模板并渲染。

    在Spring MVC中,Model、ModelMap、ModelAndView都可以作为数据模型对象,以上述类型作为控制器的方法参数时,Spring MVC会自动实例化这些类型。ModelAttribute是注解,用于定义控制器方法执行之前,对数据模型的操作。

    Spring MVC拦截器包含三个方法:preHandle()、postHandle()、afterCompletion()。 

    (拦截器,理解成断点类似的就可以了)

     拦截器需实现HandlerInterceptor接口,而WebMvcConfigurer接口是MVC配置类要实现的接口。

 

    MVC的处理过程,首先控制器接受用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。

    这里的错误选项是“模型确定调用哪个视图进行数据展示”,其实应该是“控制器确定……”。

    (这里贴出教科书的解释,比较详实,第一次看应该也能够理解。)

     在Spring MVC中实现上传功能,主要依赖MultipartHttpServletRequest从读取请求中的文件,然后对读取到的MultipartFile类型进行处理。   

    DispatcherServlet,HandlerMapping,ModelAndView是Spring MVC的核心组件。

     MVC设计模式下,Model代表的是数据,View代表的是用户界面,Controller代表的是数据的处理逻辑,它是Model和View这两层的桥梁。

 

 

  参考链接:

       https://blog.csdn.net/riemann_/article/details/118500805

       https://blog.csdn.net/xcy1193068639/article/details/81491071

       https://blog.csdn.net/isbn0123/article/details/118642699

      Spring AOP 详细深入讲解+代码示例-阿里云开发者社区 (aliyun.com)

本文作者:程序计算机人

本文链接:https://www.cnblogs.com/clina/p/18179366

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   程序计算机人  阅读(15)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Lions Pride Audio artist
  2. 2 Salty Sailor David Arkenstone
  3. 3 Stonefire David Arkenstone
Stonefire - David Arkenstone
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available