Spring复习总结

一 Spring 简介

Spring是一个轻量级的控制反转和面向切面的容器框架,用来解决企业项目开发的复杂度问题——解耦

Spring两大核心思想:IoC和AOP

  • IoC

  • AOP

  • 轻量级:体积小,对项目代码没有侵入性

  • 控制反转:IoC(Inverse of Control),把创建对象、给对象属性赋值的工作交由Spring完成;Spring在通过反射创建对象的同时可以给属性赋值(DI:依赖注入)

  • 面向切面:AOP(Aspect Oriented Programming)面向切面编程,可以在不改变原有业务代码的前提下进行业务的增强(原理:动态代理)

  • 容器:实例对象,Spring不仅可以创建对象,还可以对创建的对象进行管理。

Spring架构图

 

 

1.1 控制反转

IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

  IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

依赖注入(DI Dependency Injection)——依赖Spring容器工厂给创建的对象的属性注入值

DI注入的几种方式:

  1. set方法注入:通过反射调用属性的set方法进行属性赋值

    • 需要提供无参构造器

    • 需要提供属性的set方法

    
    ​public class Id { 
     private int id; 
     public int getId() { return id; } 
     public void setId(int id) { this.id = id; } 
    } 
    <bean id="id" class="com.id "> <property name="id" value="123"></property> </bean>

  2. 构造器注入:通过反射调用有参构造器创建对象并给属性赋值

  1. 需要提供有参构造器

    • constructor-arg标签设置参数要与构造器参数顺序一致,如果不一致需要通过index属性指定赋值给第一个参数(从0开始)


​
/*带参数,方便利用构造器进行注入*/ 
 public CatDaoImpl(String message){ 
 this. message = message; 
 } 
<bean id="CatDaoImpl" class="com.CatDaoImpl"> 
<constructor-arg value=" message "></constructor-arg> 
</bean>

3 接口注入:几乎不用

4 静态工厂注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让 spring 管理所 有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过 spring 注入的形式获 取:

public class DaoFactory { //静态工厂 
 public static final FactoryDao getStaticFactoryDaoImpl(){ 
 return new StaticFacotryDaoImpl(); 
 } 
} 
public class SpringAction { 
 private FactoryDao staticFactoryDao; //注入对象
 //注入对象的 set 方法 
 public void setStaticFactoryDao(FactoryDao staticFactoryDao) { 
 this.staticFactoryDao = staticFactoryDao; 
 } 
} 
//factory-method="getStaticFactoryDaoImpl"指定调用哪个工厂方法
 <bean name="springAction" class=" SpringAction" > 
 <!--使用静态工厂的方法注入对象,对应下面的配置文件--> 
 <property name="staticFactoryDao" ref="staticFactoryDao"></property> 
 </bean> 
 <!--此处获取对象的方式是从工厂类中获取静态方法--> 
<bean name="staticFactoryDao" class="DaoFactory" 
factory-method="getStaticFactoryDaoImpl"></bean>

5 实例工厂

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先 new 工厂类,再调用普通的 实例方法 :

public class DaoFactory { //实例工厂 
 public FactoryDao getFactoryDaoImpl(){ 
 return new FactoryDaoImpl(); 
13/04/2018 Page 128 of 283
 } 
} 
public class SpringAction { 
 private FactoryDao factoryDao; //注入对象 
 public void setFactoryDao(FactoryDao factoryDao) { 
 this.factoryDao = factoryDao; 
 } 
} 
 <bean name="springAction" class="SpringAction"> 
 <!--使用实例工厂的方法注入对象,对应下面的配置文件--> 
 <property name="factoryDao" ref="factoryDao"></property> 
 </bean> 
 <!--此处获取对象的方式是从工厂类中获取实例方法--> 
<bean name="daoFactory" class="com.DaoFactory"></bean> 
<bean name="factoryDao" factory-bean="daoFactory"
factory-method="getFactoryDaoImpl"></bean> 

自动装配

自动装配有五种自动装配的方式,可以用来指导 Spring 容器用自动装配方式来进行依赖注入。

1. no:默认的方式是不进行自动装配,通过显式设置 ref 属性来进行装配。

2. byName:通过参数名 自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设 置成 byname,之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。

3. byType:通过参数类型自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被 设置成 byType,之后容器试图匹配、装配和该 bean 的属性具有相同类型的 bean。如果有多 个 bean 符合条件,则抛出错误。

4. constructor:这个方式类似于 byType, 但是要提供给构造器参数,如果没有确定的带参数 的构造器参数类型,将会抛出异常。

5. autodetect:首先尝试使用 constructor 来自动装配,如果无法工作,则使用 byType 方式。 

1.2 面向切面

AOP (Aspect Oriented Programming)面向切面编程,是一种利用“横切”的技术(底层实现就是动态代理),对原有的业务进行拦截,并且可以在拦截的横切面上添加特定的业务逻辑,从而实现对原有业务的增强。

 

Spring 提供了两种方式来生成代理对象: JDKProxy 和 Cglib,具体使用哪种方式生成由 AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。默认的策略是如果目标类是接口, 则使用 JDK 动态代理技术,否则使用 Cglib 来生成代理。

/**
 *
 * JDK动态代理类创建规则:
 * 1.实现InvocationHandler接口,同时实现invoke方法
 * 2.在类中定义一个Object类型变量obj,提供有参构造器,用于将被代理对象传递进来
 * 3.定义一个getProxy方法返回代理对象
 */
public class JDKDynamicProxy implements InvocationHandler {

    //被代理对象
    private Object obj;
    //有参构造器
    public JDKDynamicProxy(Object obj) {
        this.obj = obj;
    }

    public Object getProxy(){
        ClassLoader classLoader = obj.getClass().getClassLoader();
        Class<?>[] interfaces = obj.getClass().getInterfaces();
        Object proxy = Proxy.newProxyInstance(classLoader,interfaces,this);
        return proxy;
    }

    /**
     * 通过此JDK动态代理类产生的代理对象,调用方法时都会执行当前invoke方法
     * @param proxy
     * @param method  指代的是通过代理对象调用的方法(insert)
     * @param args  指代的是通过被代理对象调用的方法的参数 (insert方法的参数)
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("=============start");
        Object r = method.invoke(obj, args); //执行insert方法
        System.out.println("=============commit");
        return r;
    }

}

 

/**
 *  CGLib动态代理类创建规则
 *  1.实现MethodInterceptor接口,实现intercept方法
 *  2.在类中定义一个Object类型变量obj,提供有参构造器,用于将被代理对象传递进来
 *  3.定义一个getProxy方法返回代理对象
 *
 */
public class CGLibDynamicProxy implements MethodInterceptor {

    private Object obj;
    public CGLibDynamicProxy(Object obj) {
        this.obj = obj;
    }

    public Object getProxy(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        //如果使用此动态代理类产生的代理对象调用方法,则回调此类中intercept
        enhancer.setCallback(this);      
        Object proxy = enhancer.create();
        return proxy;
    }


    /**
     * 使用此动态代理类产生的代理对象调用方法时,并不会执行被调用的方法
     * 而是执行此intercept方法,被调用的方法作为参数传递进来
     * @param o
     * @param method  被调用的方法
     * @param objects 被调用的方法的参数
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println(">>>>>>>>>>>>>>start");
        Object r = method.invoke(obj, objects);
        System.out.println(">>>>>>>>>>>>>>commit");
        return r;
    }
}

二 Spring Mvc 概述

Spring MVC是由Spring官方提供的基于MVC设计理念,通过对Servlet封装实现MVC控制的web组件(框架)

流程分析:

 ①前端放松请求被前端控制器DispatcherServlet组件拦截
②前端控制器调用处理器映射HandlerMapping组件对请求URL进行解析,解析之后返回调用链给前端控制器
③前端控制器调用处理器适配器HandlerAdapter组件处理调用链
④处理器适配器基于反射通过适配器模式调用`控制器/处理器`处理用户请求,并返回数据及视图(ModelAndView,String)信息给处理器适配器
⑤处理器适配器封装视图及数据到ModelAndView对象,将ModelAndView对象返回给前端控制器
⑥前端控制器调用视图解析器ViewResolver组件进行解析(分离视图资源和数据资源),将解析结果返回给前端控制器
⑦前端控制器调用视图View组件对视图和数据进行渲染,将渲染结果(html)返回给前端控制器
⑧前端控制器将渲染响应给用户浏览器

三 Spring boot

概述:

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭 建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的 配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

特点:

1. 创建独立的 Spring 应用程序

2. 嵌入的 Tomcat,无需部署 WAR 文件

3. 简化 Maven 配置

4. 自动配置 Spring

5. 提供生产就绪型功能,如指标,健康检查和外部配置

6. 绝对没有代码生成和对 XML 没有要求配置

Spring版本发展

  • Spring 1.x

    • 所有的spring配置只能通过xml方式完成 (<bean id="" class=""/>)

  • Spring 2.x

    • 自JDK1.5开始支持注解,Spring从2.x开始支持使用注解

    • 企业开发中到底是使用注解配置还是xml配置?

      • 对于基础配置、引用第三方依赖中的配置需要使用XML配置完成

      • 对于项目业务开发(例如:控制器类、业务类)使用注解

  • Spring 3.x

    • 开始支持基于Java类的配置(注解)

    • 自3.x版本开始:xml、注解、Java配置

java.util.Date
com.qfedu.entity.Student

3.4.2 XML配置

<bean id="date" class="java.util.Date"></bean>
<bean id="stu" class="com.qfedu.entity.Student"></bean>

3.4.3 注解配置

@Component
public class Student{
    
}

3.4.4 Java配置

@Configuration
public class MyConfig{
    
    @Bean
    public Date getDate(){
        return new Date();
    }
    
    @Bean
    public Student getStudent(){
        return new Student();
    }
    
}

四 其它

4.1 Spring,Spring MVC,Spring boot常用注解

Spring:

Spring MVC:

 

Spring boot:

@SpringBootApplication 实际指代的是一组注解,启动类注解

  • @ComponentScan注解,声明Spring容器的组件加载范围——启动类所在的包

  • @EnableAutoConfiguration注解,声明开启SpringBoot的自动配置

  • @SpringBootConfiguration注解,声明启动类同时为Spring的配置类(在配置类中定义方法,在方法上添加@Bean注解,就可以将方法返回的对象存放到Spring容器)

2 Spring boot启动及自动装配原理

自动配置原理:SpringBoot的自动配置就是通过自定义实现ImportSelector接口,然后通过SpringFactoriesLoader扫描autoconfigure包下的META-INF/spring.factories中所有路径下的类,并通过反射实例化成一个个的配置类并注入到Spring容器中,从而实现了自动装配,

  引用一下大佬的文章

Springboot 起步依赖和自动配置实现过程

 

3 Spring boot 中的starter

可以看成是对依赖的一种合成,starter会把一个或者一套功能相关的依赖导入进来,避免自己去导入依赖包以及解决依赖冲突问题.

4 Spring boot配置拦截器

创建拦截器-实现 HandlerInterceptor接口

 

配置拦截器路径-实现WebMvcConfigurer接口

 4 springboot 全局异常处理

四种处理全局异常方式

常用的有

使用注解@ExeceptionHandler 

使用HandlerExceptionResolver自定义全局处理异常类

总结:后续继续更新,脑子一团糟...

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值