Spring

143 阅读5分钟

Spring

是一个IOC和AOP的轻量级容器框架

IOC
  1. 控制反装:对象交由Spring来创建,通过DI依赖注入来实现IOC,原理是工厂模式+反射机制

    1. ApplicationConext是BeanFactory的子接口,主要用来生成bean
    2. 反射机制:在程序运行过程中,动态的获取类的属性和对象,如class.forName获取数据库驱动
  2. 依赖注入方式:构造方法注入,Setter注入,工厂方式注入

  3. Bean的装配方式:xml配置,注解@,javaConfig

  4. 代理模式:把对象包装起来,对对象的调用都要经过这个包装类

  5. 静态代理:在多态的形式上给实现类创建一个代理类,有重复编码的问题

    1. 多态:同一类对象调用同一个方法表现出不同的行为特征
    2. 继承/实现;父类引用指向子类对象;方法重写
  6. 动态代理:在程序运行过程中,通过反射机制动态创建代理类,比如AOP

  7. IOC加载过程/Bean的生命周期

    1. 首先实例化一个ApplicationContext对象,通过Bean工厂扫描解析类的信息,保存到一个BeanDeifination对象里,然后通过构造方法反射实例化一个对象,进行属性注入,注入完成后根据Bean的类型去调用生命周期接口方法完成初始化操作,如果实现了AOP,就创建动态代理,到此bean创建完成,放到spring容器里,spring容器关闭,bean就销毁了
    2. BeanDeifination是Bean的定义,包含了类的所有信息,属性,类型,作用域等
    3. Bean的类型:BeanNameAware,BeanFactoryAware
  8. BeanPostProcessor:后置处理器,是Spring IOC容器提供的一个扩展接口,有两个抽象方法,可以在bean初始化方法调用前后做一些逻辑处理

  9. Bean创建细节

    /**
     * 1) 对象创建: 单例/多例
     * scope="singleton", 默认值, 即 默认是单例 【service/dao/⼯具类】 线程不安全
     * scope="prototype", 多例; 【Action对象】
    
     * 2) 什么时候创建?
     * scope="prototype" 在⽤到对象的时候,才创建对象。
     * scope="singleton" 在启动(容器初始化之前), 就已经创建了bean,且整个应⽤只有⼀个。
    
     * 3)是否延迟创建
     * lazy-init="false" 默认为false, 不延迟创建,即在启动时候就创建对象
     * lazy-init="true" 延迟初始化, 在⽤到对象的时候才创建对象(只对单例有效)
     */
    
AOP
  1. 面向切面编程,就是分离关注点,在不改变源代码的情况下动态的给程序添加一些功能,实质上就是拦截对象方法,对方法进行改造,增强,比如日志,事务,这些都是相同逻辑的重复代码,可以横向抽取出来,用动态代理把这些重复代码织入到目标对象方法中,实现和原来⼀样的功能,这样我们在写业务的时候只需要关心业务代码

  2. AOP术语

    1. 连接点(Join point):能够被拦截的地⽅:Spring AOP是基于动态代理的,所以是⽅法拦截的
    2. 增强/通知(Advice):5种Advice
    3. 织⼊(Weaving):将 增强/通知 添加到目标类的具体连接点上的过程
  3. AOP的实现者

    1. SpringAOP

      1. Spring AOP构建在动态代理基础之上,所以,Spring对AOP的支持局限于方法拦截

      2. 在Java中动态代理有两种方式

        1. Spring AOP默认是JDK动态代理,他实现的是某个接口
        2. 多例使用JDK,因为他创建代理对象的性能比CGLib高
      3. CGLib动态代理

        1. 如果没有接口,可以用CGLib,他生成的动态代理对象是目标类的子类
        2. 单例使用CGLib,生成代理对象的性能比JDK高
      4. 提供了3种类型的AOP支持

        1. 基于代理的,需要实现接口,手动创建代理
        2. 纯POJO切面,使用xml配置,aop命名空间
        3. @AspectJ注解驱动的切面
    2. AspectJ

      1. 静态织入,支持编译时、编译后和类加载时织入,有专门的编译器,SpringAOP只能在运行时织入,不需要编译器
      2. AspectJ支持所有切入点,SpringAOP只支持方法执行切入点
    3. JBoss AOP

  4. 常用注解

    1. @Aspect:定义一个切面类
    2. @Component:让类交由Spring管理
    3. @Pointcut:定义一个切面,即某件事的入口(常用的表达式:execution)
    4. @Before:在做某件事之前做的事;前置通知
    5. @After:在做某件事之后做的事;后置通知
    6. @AfterReturning:在做完某件事之后,对其返回值做增强处理;返回通知
    7. @AfterThrowing:在做某件事抛出异常时,处理;异常通知
    8. @Around:环绕通知
  5. 流程:解析切面,创建动态代理对象,调用方法

  6. 作用:记录请求URL,参数,流水号,返回值,处理时间等

SpringMVC

  1. 基本流程

    1. 用户请求url地址
    2. 前端控制器dispatcherServlet(接收请求,响应结果)根据url信息和HandlerMapper映射地址去找到相应的Controller
    3. Controller处理完成后返回一个ModelAndView
    4. dispatcherServlet根据返回的试图名去调用试图解析器去解析成真正的view,加渲染返回给浏览器
  2. SpringMVC是单例模式,在多线程访问时会有线程安全问题

    1. 在控制器中不使用实例变量(全局变量),线程安全问题归根结底就是数据共享
    2. 将控制器的作用域从单例改为原型,scope="prototype",每次都会创建新的Controller
    3. 在控制器中使用ThreadLoacl维护变量
  3. SpringMVC的注解

    1. @RestController = @Controller+@ResponseBody

    2. @Controller 定义一个controller类

    3. @RequestMapping:请求映射的注解

      1. @RequestParam:获取请求参数(是从request上获取参数值);@PathVariable(是从url上获取参数值)
    4. @RequestBody:把接收的Json转换成Java对象

    5. @ResponseBody:把Java对象转成Json响应给用户