Spring(Day2)

news2025/1/22 17:51:48

一、静态代理

    静态代理的主要特点是代理类和被代理类通常具有相同的接口,这样客户端代码可以透明地使用代理类代替被代理类。

  首先我们建立一个接口Shopping,在里面定义一个shopping方法。然后创建两个类EasyA和Proxy类来继承Shopping类,并重写里面的方法。将EasyA类作为被代理类,Proxy类作为代理类,我们只需要调用代理类,让它帮我们封装被代理类。

  在代理类中,我们声明一个被代理类的类型变量,并将他作为参数定义构造函数,在代理类中重写的方法不仅调用了被代理类的对象的方法,还在它的前后写上了日志。

  在主函数中,我们首先声明一个被代理类的对象,然后将其作为参数传入代理类,然后执行主函数,代理类调用被代理类的方法。

接口代码:

package com.easy.staticproxy;

public interface Shopping {

    void shopping();
}

被代理类代码:

package com.easy.staticproxy;

public class EasyA implements Shopping{
    @Override
    public void shopping() {
        System.out.println("去购物");
    }
}

代理类代码:

package com.easy.staticproxy;

public class Proxy implements Shopping{

    Shopping s;
    public Proxy(Shopping s){
        this.s=s;
    }
    @Override
    public void shopping() {
        System.out.println("-----1111");
        s.shopping();
        System.out.println("-----2222");
    }
}

主函数代码:

package com.easy.staticproxy;

public class Factory {
    public static Shopping getShopping(){
        EasyA a=new EasyA();
        Shopping s=new Proxy(a);
        return s;
    }

    public static void main(String[] args) {
        Shopping shopping=getShopping();
        shopping.shopping();
    }
}

二、动态代理

通过动态生成一个代理对象,这个代理对象通过getProxy方法获取了参数所实现的所有接口,比如被代理类实现的EasyInterface接口/Shopping接口。当shopping方法被调用时,会执行EasyInvocationhandler类中的invoke方法。在invoke方法中,首先输出 "-----执行方法之前添加的业务"。然后调用实际的EasyA对象的shopping方法。最后输出 "执行方法之后的处理"。

接口:

package com.easy.staticproxy.dynamic.jdk;

public interface EasyInterface {

    void easy();
}

被代理类:

package com.easy.staticproxy.dynamic.jdk;

public class EasyObj implements EasyInterface{
    @Override
    public void easy() {
        System.out.println("---正常业务逻辑");
    }
}
package com.easy.staticproxy.dynamic.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class EasyInvocationhandler implements InvocationHandler {

    private Object proxyedObj;//被代理对象

   public EasyInvocationhandler(Object proxyedObj){
        this.proxyedObj=proxyedObj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=null;//定义方法的返回值对象
        System.out.println("-----执行方法之前添加的业务");
        //正常执行业务逻辑
        result =method.invoke(proxyedObj,args);
        System.out.println("执行方法之后的处理");
        return result;
    }
}

这里的关键点在于Proxy.newProxyInstance方法的第三个参数,即EasyInvocationhandler实例。这个实例实现了InvocationHandler接口,并且重写了invoke方法。
invoke方法的作用
当代理对象的方法被调用时,实际调用的是EasyInvocationhandler类中的invoke方法。这是因为代理对象是通过Proxy.newProxyInstance创建的,它会捕获所有的方法调用,并将它们转发给EasyInvocationhandler的invoke方法。

主函数:

package com.easy.staticproxy.dynamic.jdk;

import com.easy.staticproxy.EasyA;
import com.easy.staticproxy.Shopping;

import java.lang.reflect.Proxy;

public class Factory {

    public static Object getProxy(Object obj){
        //JDK代理只能实现接口中的方法
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),//类加载器
               obj.getClass().getInterfaces(),//实现的接口
        new EasyInvocationhandler(obj));
    }

    public static void main(String[] args) {
        EasyObj easy=new EasyObj();
        Object obj=getProxy(easy);//动态生成的一个代理类的对象
//        System.out.println(obj);
        if(obj instanceof EasyInterface){
            System.out.println("obj是代理对象是EasyInterface的实例");
            EasyInterface e=(EasyInterface) obj;
            e.easy();
        }
//        Class c=obj.getClass();
//        System.out.println(c);

        EasyA easya=new EasyA();
        obj=getProxy(easya);
        System.out.println(obj instanceof Shopping);
        Shopping s=(Shopping) obj;
        s.shopping();
//        System.out.println(obj.getClass());
    }
}

三、AOP

通过@Aspect来标注当前面是一个切面

我们可以通过@Pointcut注解来定义被拦截的方法,可以设置下面的五种通知方式

下面是示例代码:

package com.easy.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AOPObj {

    //定义切点
    @Pointcut("execution(* com.easy.controller.EasyAController.testA(..))")
    public void pointCuttesta(){}
    @Before("pointCuttesta()")
    public void before(){
        System.out.println("---前置通知");
    }
}

我们将切入点设在了EasyController类中调用TestA类的方法时,并且设置成在调用方法前进行通知,我们执行代码并访问页面调用TestA中的方法,控制台输出结果如下:

后两行是test方法中定义的操作。

四、接收前端参数

我们在类的前面用@Requestmapping定义出一级路径。

1.方法的参数名称和前台传递的参数名一样

 @RequestMapping("parama")
    public String paramA(String name){
        return "springmvc接收到的参数是:"+name;
    }

我们在前台输入的时候也应该是name

我们在地址上面写name=张三,所以它输出的就是张三

2.同时接受多个参数 Map接收 非常灵活 有安全问题

  @RequestMapping("paramb")
    public Map paramb(@RequestParam Map params){
        return params;
    }

@RequestParam Map params: 表示从HTTP请求中读取所有的请求参数,并将它们作为键值对存储在一个Map中。这里的params就是用来接收这些键值对的变量。

我们在地址上填入什么都可以被写入Map,这很不安全。

3.封装对象来接收参数 程序中只接收我们需要的数据

我们定义一个Staff类,里面有id,name,salary这三个属性,我们将Staff类的对象当做参数传入,只有在Staff中定义的属性才能被写入。

Staff类的代码

package com.easy.bean;

public class Staff {
    private Integer id;
    private String name;
    private int salary;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}
@RequestMapping("paramc")
    public Staff paramc(Staff staff){
        return staff;
    }

我们没有传入id所以它显示的是null,我们输入age但是Staff中未定义,所以他也无法写入。

4.获取地址上的参数

@RequestMapping("paramd/{id}")
    public String paramd(@PathVariable Integer id, HttpServletRequest request){
        String username=request.getParameter("username");
        return "接收到的参数是:"+id+"----"+username;
    }

@PathVariable从 URL 中提取路径变量,并将这些变量用作方法参数。

从地址上获取参数id=12。

作用域

五、转发和重定向

1.转发:同一个服务器中不同的服务进行转发

浏览器发送了一个请求 可以转发到项目中受保护的资源WEB-INF
转发是request对象执行forward方法

 @RequestMapping("methoda")
    public String methodA(){
        System.out.println("---methodA");
        return "forward:/methodb";
    }
    @RequestMapping("methodb")
    @ResponseBody
    public String methodB(){
        System.out.println("---methodB");
        return "this is methodB";
    }

当我们输入methodA的地址时,它显示的是methodB中的方法,但地址不会改变,说明浏览器只发送了一次请求。

2.重定向:可以在不同的服务之间跳转

浏览器发送了两次请求
重定向是通过response对象通知浏览器重新访问   redirect
    @RequestMapping("methoda")
    public String methodA(){
        System.out.println("---methodA");
//        return "forward:/methodb";
//        return "redirect:/methodb";//重定向
        return "redirect:http://www.baidu.com";
    }
    @RequestMapping("methodb")
    @ResponseBody
    public String methodB(){
        System.out.println("---methodB");
        return "this is methodB";
    }

在methodA中输入methodB的地址或者百度的地址,浏览器请求一次,然后methodA将methodB或者百度的地址回复给浏览器,然后浏览器按照地址进行第二次请求。

六、拦截器

定义一个类来继承HandlerInterceptor接口,重写里面的三个方法,使它们分别在方法调用前,调用后、请求处理完毕后打印日志。

拦截器代码

package com.easy.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class EasyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("----preHandle");
//        return HandlerInterceptor.super.preHandle(request, response, handler);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("----postHandle");
//        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("----afterCompletion---整个请求处理完毕");
//        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
@RequestMapping("methodc")
    @ResponseBody
    public String methodC(){
        System.out.println("---methodc");
        return "index.jsp";
    }

执行代码后,输入地址后会显示index.jsp字符串。日志打印结果如下

七、全局控制

首先定义一个Staff类

package com.easy.bean;

public class Staff {

    private int id;
    private String name;
    private String sex;
    private int salary;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

然后我们通过CommonResult类定义返回结果的格式

package com.easy.common;


public class CommonResult {
    private int code;
    private String message;
    private Object data;

    public CommonResult(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public static CommonResult success(int code, String message, Object data) {
        return new CommonResult(code, message, data);
    }
    public static CommonResult success(int code, String message) {
        return new CommonResult(code, message, null);
    }
    public static CommonResult success(Object data) {
        return new CommonResult(200, "操作成功", data);
    }
    public static CommonResult success() {
        return new CommonResult(200, "操作成功", null);
    }

    public static CommonResult fail(int code, String message, Object data) {
        return new CommonResult(code, message, data);
    }
    public static CommonResult fail(int code, String message) {
        return new CommonResult(code, message, null);
    }
    public static CommonResult fail(){
        return new CommonResult(400,"操作失败",null);
    }


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

下面是增删改查Staff类对象的代码实现,每个都默认会返回成功的结果。

@ExceptionHandler(Exception.class) 注解用于指定一个方法来处理特定类型的异常。在这个例子中,它处理所有类型的Exception异常。当一个异常被抛出时,Spring框架会检查是否有用此注解标记的方法,并调用它来处理异常。

package com.easy.controller;

import com.easy.bean.Staff;
import com.easy.common.CommonResult;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@ControllerAdvice//全局控制
//@RequestMapping("staff")
public class StaffController {

    @GetMapping("staff")
    public CommonResult getList(Staff staff){
        List<Staff> list=null;
        System.out.println("获取数据");
        return CommonResult.success(list);
    }
    @PostMapping("staff")
    public CommonResult addStaff(Staff staff){
        System.out.println("新增数据");
        return CommonResult.success();
    }
    @DeleteMapping("staff/{id}")
    public CommonResult deleteStaff(@PathVariable int id){
        System.out.println("删除数据"+id);
        return CommonResult.success();
    }

    @PutMapping("staff")
    public CommonResult editStaff(Staff staff){
        System.out.println("编辑数据");
        return CommonResult.success();
    }

    @RequestMapping("ex")
    public CommonResult ex(){
        int a=12/0;
        return CommonResult.success();
    }
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public CommonResult exh(){
        return CommonResult.success(200,"11111");
    }
}

输入@ControllerAdvice就是全局控制,不写的话就只能控制本类。

八、SpringMVC运行原理

1.用户通过浏览器发起一个 HTTP 请求,该请求会被 DispatcherServlet(前端控制器)拦截;
2.DispatcherServlet 调用 HandlerMapping(处理器映射器)找到具体的处理器(Handler)及拦截器,
3.HandlerMapping将Handler以 HandlerExecutionChain 执行链的形式返回给 DispatcherServlet。
4.DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
5.HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(即 Controller 控制器)对请求进行处理;
6.Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC 的底层对象,包括 Model 数据模型和 View 视图信息);
7.HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
8.DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
9.ViewResolver 解析完成后,会将 View 视图并返回给 DispatcherServlet;
10.DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
11.视图负责将结果显示到浏览器(客户端)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1978296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端 react 实现图片上传前压缩 缩率图

目录 一、安装 二、编写工具类 三、获取压缩后的File对象 一、安装 npm install compressorjs 或 yarn add compressorjs 官方文档&#xff1a;compressorjs - npm (npmjs.com) 二、编写工具类 /*** author Dragon Wu* since 2024/8/4 12:23* 图片压缩工具*/ import Com…

《无畏契约》现已正式登陆Xbox Series X|S和PS5主机

拳头游戏日前已在没有任何通知的情况下直接在 Xbox Series X|S 和 PS5 主机上推出了其竞技射击游戏《无畏契约》。经过6 月的短暂测试后&#xff0c;游戏的主机版已经在美国、加拿大、欧洲、日本和巴西推出&#xff0c;将包括与 PC 版相同的玩法、英雄和技能。 主机版本将永远不…

论网络流(最大流篇)--新手入门超详解--包教包会

论网络流--新手入门超详解--包教包会 1 前言2 什么是最大流3最大流问题的求解&#xff08;1&#xff09;问题转化--增广路的引入&#xff08;2&#xff09;走回头路--EK算法&#xff08;3&#xff09;EK的弊端&#xff08;4&#xff09;化图为树--DINIC算法 4后记 1 前言 网络…

小型空气净化器什么牌子好?小型空气净化器用户体验

自从家里有了4只英短后&#xff0c;一到季节我就得不停的拖地刷床&#xff0c;除了这些可以手动清理的猫毛之外&#xff0c;那么空气中的猫毛怎么办&#xff1f;多猫家庭确实很快乐&#xff0c;但一到换毛季&#xff0c;家里地上、空气里全是猫毛。每天都需要拼命的吸地板&…

Linux命令用法

文章目录 前言一、Linux基础命令1. Linux目录结构2. Linux命令入门3. 目录切换相关命令&#xff08;cd、pwd&#xff09;4. 相对路径、绝对路径和特殊路径符5. 创建目录命令&#xff08;(mkdir&#xff09;6. 文件操作命令part1(touch、cat、more&#xff09;7. 文件操作命令pa…

经验分享|temu电商项目怎么做能更好的盈利?

在当今竞争激烈的电商市场中&#xff0c;如何让TEMU这样的电商项目实现更好的盈利&#xff0c;是每个创业者和企业家关注的核心问题。以下是几点关键的策略和方法&#xff0c;可以帮助TEMU电商项目实现更好的盈利。 首先&#xff0c;产品选择和定位至关重要 TEMU需要选择具有市…

黑马Java零基础视频教程精华部分_10_面向对象进阶(2)_多态、包、final、权限修饰符、代码块

系列文章目录 文章目录 系列文章目录一、多态1、什么是多态&#xff1f;2、多态的表现形式3、多态的前提4、多态的好处5、多态调用成员的特点6、多态的优势和弊端7、引用数据类型的类型转换 二、包1、什么是包&#xff1f;2、包名的规则3、使用其他类的规则 三、final 最终的&a…

通过指令深入了解Linux

1.简单介绍XShell 未来我的所有关于Linux的讲解都是提供XShell登入远程的Linux云服务器来教学的&#xff0c;且以centos为例。 1.1下载安装XShell xshell 下载安装时选择“home/school”为免费版本。 1.2 使用XShell登录主机 在XShell终端输入 ssh rootip ip为你所购买的…

功能实现——使用 RestTemplate 进行跨项目接口调用

目录 1.需求说明2.项目环境搭建3.代码实现3.1.使用 RestTemplate 进行调用3.1.1.项目 A3.1.2.项目 B 3.2.测试3.3.使用 JsonObject 来传递和接收 json 数据3.3.1.说明3.3.2.代码实现 3.4.其它说明3.4.1.restTemplate.exchange()3.4.2.restTemplate.postForObject()3.4.3.区别总…

【Java】Java学生成绩管理系统(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Ubuntu 18.04,调整字体大小, 隐藏GNOME顶部状态栏

先安装 sudo apt-get install gnome-tweak-tool sudo apt install gnome-shell-extensions 安装后出现这个界面 这里可以调整字体大小 安装工具扩展&#xff1a; sudo apt-get install gnome-shell-extension-autohidetopbar 这里可以出现设置项 打开&#xff0c;并且…

【Altium Designer】Details Net has only one pin (Pin U1-12) 解决办法

报错图&#xff1a; 报错含义&#xff1a; Details Net has only one pin (Pin U1-12) 引脚label没接其他元器件。 解决办法1 修改报告提示&#xff0c;将“错误”改为“不报告”&#xff0c;如下图&#xff0c;在工程上 右键>>工程选项>>找到相应的错误标签提示…

个人主体的小程序可以变更为企业主体吗?

小程序迁移变更主体有什么作用&#xff1f;长期以来&#xff0c;由于部分小程序在注册时&#xff0c;主体不准确的历史原因&#xff0c;或者小程序的主体发生合并、分立或业务调整等现实状况&#xff0c;在小程序登记主体不能对应实际运营人的情况下&#xff0c;导致账号在认证…

基于微信小程序的微课堂笔记的设计与实现(源码+论文+部署讲解等)

博主介绍&#xff1a;✌全网粉丝10W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术栈介绍&#xff1a;我是程序员阿龙&#xff…

【MongoDB数据库之未授权漏洞】

步骤一&#xff1a; 在Kali上执行以下命令搭建起MongoDB的漏洞环境.. 拉取mongo(3.6.6版本)镜像 docker pull mongo:3.6.6 启动镜像 docker run --name mongo-master -p 27017:27017 -d mongo:3.6.6 查看镜像 docker ps 步骤二&#xff1a;使用Nmap的插件脚本进行扫描..发现…

RIR转换Revit尺寸标注和值到Rhino指定图层中

RIR转换Revit尺寸标注和值到Rhino指定图层中 1、使用新增的Dimension Properties节点&#xff0c;获取尺寸标注的线和文字 2、通过elefont包的节点&#xff0c;将起按指定图层bake到rhino中 3、funbim v0.6.4版本节点包已更新到food4rhino&#xff0c;欢迎下载试用

平安养老险宿州中支参加中国特色金融文化“我在行动”演讲比赛

为积极培育和弘扬以“五要五不”为核心的中国特色金融文化&#xff0c;积极传播保险行业正能量&#xff0c;7月30日&#xff0c;由宿州市保险行业协会主办的培育和弘扬中国特色金融文化“我在行动”演讲比赛拉开帷幕。本次演讲比赛共有16位选手参与&#xff0c;平安养老保险股份…

社区检测算法(Community Detection)总结

社区检测(Community Detection) 社区检测&#xff08;Community Detection&#xff09;又被称为是社区发现。它是用来揭示网络聚集行为的一种技术。 社区检测算法用于评估节点组如何聚类或分区&#xff0c;以及它们增强或分离的趋势。 社区 社区是许多网络的属性&#xff0c;…

运维团队可视化大屏定制指南

在运维工作中&#xff0c;可视化大屏作为实时监控和数据分析的重要工具&#xff0c;其直观性和灵活性对于提高运维效率和决策质量至关重要。本文将结合运维行业的特点&#xff0c;为运维团队提供可视化大屏定制化的参考指南。 一、可视化大屏的默认配置与定制化需求 可视化大屏…

java 如何查看jar版本冲突,如何查看哪个模块依赖冲突,idea查看jar包冲突

1. idea 下载插件&#xff1a; 2. 如上图所示&#xff0c;下载Maven Helper, 注意是maven helper 不是别的 3.重启idea 4.点击pom文件&#xff0c;然后点击如图所示&#xff1a; 5. 如此即可查到&#xff0c;某个jar包 都有哪个模块依赖&#xff0c;使用的什么版本&#xff0…