Spring MVC知识

1 Spring 框架

Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。

Spring 自带 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、可以很方便地集成第三方组件(电子邮件,任务,调度,缓存等等)、对单元测试支持比较好、支持 RESTful Java 应用程序的开发。

构建最基础的Spring项目

1.1 核心容器四个包

  1. spring-beans-4.1.3.RELEASE.jar
    • 这个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI 支持,引入spring-core.jar 及spring-beans.jar 文件就可以了。 外部依赖spring-core,(CGLIB)。
  2. spring-context-4.1.3.RELEASE.jar
    • 这个jar 文件为Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。 外部依赖spring-beans, (spring-aop)。
  3. spring-core-4.1.3.RELEASE.jar
    • 这个jar 文件包含Spring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。 外部依赖Commons Logging, (Log4J)。
  4. spring-expression-4.1.3.RELEASE.jar

1.2 核心容器依赖的日志包

  1. commons-logging-1.2.jar  当于一个日志接口,log4j相当于该接口的实现,如果不添加log4j包也可以,因为commons-logging也有一个简单的实现会自动使用。
  2. log4j-1.2.17.jar

1.3 测试类包

  1. spring-test-4.1.3.RELEASE.jar
  2. junit-4.10.jar(高于4.10版本还需要hamcrest-core.jar + hamcrest-library.jar)

1.4 测试类用到了AOP必须导入aop包

       1. spring-aop-4.1.3.RELEASE.jar

 

1.1 IOC: 控制反转,依赖注入(DI)。比喻A对象创建时,注入到Spring容器,容器会为A对象依赖注入所需要的B对象,由主动变为被动。

Spring提供实现IoC容器的两种方式(两个接口)

1)BeanFactory :IoC容器基本实现,是Spring内部使用的接口,不提供开发人员使用。
BeanFactory加载配置文件时不创建对象,在获取对象(使用)时才创建
2)ApplicationContext :实际是BeanFactory的子接口,提供更强大的功能,提供给开发人员使用。ApplicationContext加载配置文件时就创建对象

https://blog.csdn.net/weixin_44775375/article/details/124958143

1.2 AOP: 分为JDK动态代理(实现了接口的类生成代理),CGlib动态代理(类实现代理)

https://www.cnblogs.com/flashsun/p/7286475.html

什么时候用JDK动态代理,什么时候用CJLIB动态代理
1、目标对象生成了接口 默认用JDK动态代理
2、如果目标对象使用了接口,可以强制使用cglib
3、如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换
Cglib和JDK的效率比较
1、cglib底层是ASM字节码生成框架,但是字节码技术生成代理类,在JDL1.8之后比使用java反射的效率要低
2、Cglib不能对声明final的方法进行代理,因为cglib是动态生成代理对象,final关键字修饰的类不可变只能被引用不能被修改
Spring如何选择是用JDK还是cglib
1、当bean实现接口时,会用JDK代理模式
2、当bean没有实现接口,用cglib实现
3、可以强制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxyt-target-class=”true”/>)


AOP的应用场景
1.日志处理
2.用户登录
3.权限(Authentication )
4.性能优化(Performance optimization)
5.事务(Transactions )
6.记录跟踪 优化 校准(logging, tracing, profiling and monitoring)
7.调试(Debugging)
8.懒加载(Lazy loading)
9.错误处理(Error handling)
10.资源池(Resource pooling)
11.同步(Synchronization)

  • JDK动态代理最简代码(需要会lambda,反射知识才能看懂)
public static void main(String[] args) { //主方法
    ClacInterface myClac = new MyClac(); //被代理的对象
    //生成了一个代理类对象proxyBean
    ClacInterface proxyBean = (ClacInterface)Proxy.newProxyInstance(
         //第一个参数被代理类的类加载器
          myClac.getClass().getClassLoader(), 
          //第二个参数myClac的所以实现接口
          myClac.getClass().getInterfaces(),
          //第三参数是InvocationHandler 这里是lambda简化的匿名内部类写法
          (a, b, c) -> {
              System.out.println("我代理了myClac对象");
              return b.invoke(myClac, c);
            } );
     System.out.println("proxyBean.add(1, 3) = " + proxyBean.add(1, 3));
  }

//创建接口
public interface ClacInterface { int add(int a ,int b ); } //实现接口类 public class MyClac implements ClacInterface{ @Override public int add(int a, int b) { System.out.println("a+b"+"="+(a+b)); return a+b; } }
  • CGlib动态代理代码
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @program: CGLibProxy
 * @description: cglib的动态代理
 * @author: 辰兮要努力
 * @create: 2021-10-25 21:05
 */
public class CGLibProxy implements MethodInterceptor {

    // CGlib需要代理的目标对象
    private Object targetObject;

    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        //1.工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(obj.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类(代理对象)
        Object proxyObj = enhancer.create();
        return proxyObj;
    }


    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //模拟一下新增部分业务逻辑
        handle();
        System.out.println("这是增强方法前......");
        System.out.println("获取拦截方法:" + method.getName());
        System.out.println("获取方法参数:" + Arrays.toString(args));
        System.out.println("MethodProxy:" + methodProxy);
        Object obj = method.invoke(targetObject, args);
        System.out.println("这是增强方法后......");

        return obj;
    }

    private void handle(){
        //处理一些业务逻辑
        System.out.println("CGLibProxy处理业务逻辑");
    }

}



//创建一个user对象
@Data
public class User {

    private String id;
    private String name;
    private Integer age;

}


//创建一个接口
public interface UserManager {
    public void addUser(String id, String userName);
}

//创建如上接口的实现类
public class UserManagerImpl implements UserManager {

    @Override
    public void addUser(String id, String password) {
        System.out.println("调用了UserManagerImpl.addUser()方法!"+id+"-"+password);
    }

}
View Code
/**
 * @program: demo
 * @description: ProxyTest 测试类
 */
public class ProxyTest {

    public static void main(String[] args) {
        /**
         * 优点:基于字节码生成真实对象的子类;运行效率高于JDK 代理;真实对象不需要实现接口
         * 缺点:需要额外导入jar包
         *
         * cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理(子类也是动态代理对象)
         */
        UserManager userManagerCGLib = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());
        System.out.println("CGLibProxy:");
        userManagerCGLib.addUser("1", "chenXI");
    }
}
View Code

 

 

 

2 什么是Spring MVC

  • MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。

  • 是将业务逻辑、数据、显示分离的方法来组织代码。

  • MVC主要作用是降低了视图与业务逻辑间的双向偶合。

  • MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。

Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。

View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。

Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。

@Controller注解类型用于声明Spring类的实例是一个控制器

3 SpringMVC执行原理

前端控制器DispatcherServlet(接收请求)-> 调用 处理器映射器HandlerMapping(将请求URL和方法建立关系映射)->  请求执行Handlder -> 处理器适配器HandlerAdapter(调用具体方法)-> 请求控制器Controller -> 委托Model进行处理(Service和Dao)-> 返回给控制器 -> 返回给视图解析器 ViewResolver -> 返回视图前端控制器DispatcherServlet(响应)

 

 

 1. 前端控制器 DispatcherServlet(不需要程序员开发) --> 接收请求、响应结果,相当于转发器

 2. 处理器映射器HandlerMapping(不需要程序员开发) --> 根据请求的URL来查找Handler

 3. 处理器适配器HandlerAdapter --> 按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler

 4. 处理器Handler(需要程序员开发) --> 按照具体的请求让Controller执行

 5. 视图解析器 ViewResolver(不需要程序员开发)

 

  • DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求(Strust2 --> Springboot)
  • HandlerMapping为处理器映射。DispatcherServlet调用 HandlerMapping,HandlerMapping根据请求url查找Handler。

  • HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

  • HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  • HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

  • Handler让具体的Controller执行。

  • Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  • HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

  • DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

  • 视图解析器将解析的逻辑视图名传给DispatcherServlet。

  • DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

  • 最终视图呈现给用户。

 

 

 Model1:

 

 Model2:

 

 SpringMVC

 

 

 

4 Spring bean生命周期

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点

 

 

 

 

 

5 RestFul风格

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

资源:互联网所有的事物都可以被抽象为资源

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。

分别对应 添加、 删除、修改、查询。

传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get

 

 

资源

https://www.cnblogs.com/twq46/p/16601237.html

 

posted @ 2022-11-21 15:18  NingShare  阅读(28)  评论(0编辑  收藏  举报