StudyStudyStudy第十六天(2024.8.2)

1.代理模式

代理模式分为静态代理和动态代理

代理模式,就是在想要执行的代码之前或之后添加代码块,并不会破坏原有的代码结构。可以理解成加上了一个访问层

1.静态代理

创建一个接口Shopping

java 复制代码
public interface Shopping {
    void shopping();
}

创建一个EasyA类实现接口Shopping,重写shopping方法

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

创建一个Proxy类,实现接口,重写shopping方法

java 复制代码
public class Proxy implements Shopping{
    Shopping s;
    public Proxy(Shopping s){
        this.s=s;
    }
    @Override
    public void shopping() {
        System.out.println("--------- 一支穿云箭");
        s.shopping();
        System.out.println("--------- 千军万马来相见");
    }
}

创建一个工厂类,主函数在这个类中演示

java 复制代码
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();
    }
}

最终效果为:

可以将两段输出-----,想象成添加的访问层

静态代理的优点:1.易于理解

静态代理的缺点:1.代码冗余 2.不易维护

2.动态代理

1.JDK动态代理 组合,被代理类必须实现接口

创建一个接口 EasyInterface

java 复制代码
public interface EasyInterface {
    void easy();
}

创建一个类实现接口

java 复制代码
public class EasyObj implements EasyInterface{
    @Override
    public void easy() {
        System.out.println("---- 正常业务逻辑");
    }
}

创建第二个类(被代理对象,必须实现接口)

java 复制代码
public class EasyInvocationHandler implements InvocationHandler {
    private Object proxyedObj;//被代理对象
    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;
    }
}

创建一个工厂类:

java 复制代码
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);//动态生成的一个代理类的对象
        if (obj instanceof EasyInterface){
            System.out.println("obj是代理对象,是EasyInterface的实例");
        }
        Class c=obj.getClass();
        System.out.println(c);

        EasyA easya=new EasyA();
        obj=getproxy(easya);
        System.out.println(obj.getClass());
    }
}

2.CGLIB动态代理 继承,被代理类不能被final修饰

java 复制代码
@Component
public class EasyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("----preHandle");
        return true;
    }

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

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("----afterCompletion--整个请求处理完毕");
    }
}
java 复制代码
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    EasyInterceptor easyInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(easyInterceptor).addPathPatterns("/methodc");
    }
}

2.AOP

定义:

AOP (Aspect Orient Programming),直译过来就是 面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向切面编程,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。

作用:

AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离

AOP中一些专业术语:

Spring AOP中通知的分类:

3.SpringMVC

1.两种Controller注解的区别

两种Controller注解分别为:@Controller @RestController

当在类上写@Controller注解时,类中被标注为@RestMapping的方法的返回值,会被识别为地址,即我们在网址栏填写的地址。

当在类上写@RestController注解时,类中被标注为@RestMapping的方法的返回值,会被识别为返回内容。

2.@RestMapping注解

1.注解在方法时

当在类中方法标识上@RestMapping注解,在网站输入框中输入 http:/localhost:8080/注解地址,就会跳转到地址页

java 复制代码
@RestController //Rest  请求资源状态转换
public class EasyDController {
    @RequestMapping("nice")
    public String nice(){
        return "NICE METHOD";
    }
}

2.注解在类时

注解在类时,需要在地址栏先输入父层地址,再输入子层地址

java 复制代码
@RestController //Rest  请求资源状态转换
@RequestMapping("user")
public class EasyDController {
    @RequestMapping("nice")
    public String nice(){
        return "NICE METHOD";
    }
}

3.@PathVariable注解

不添加@PathVariable注解时需要在地址栏按实参填入

java 复制代码
@RestController //Rest  请求资源状态转换
@RequestMapping("user")
public class EasyDController {
    //接收前端的参数   方法的参数名称和前台传递的参数名一样才可以接收到
    @RequestMapping("parama")
    public String paramA(String name){
        return "SpringMVC接收到的参数是:"+name;
    }

}

在方法参数列表中填入,在地址栏就不需要按照实参名称输入值

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

4.请求转发 和 重定向 的区别

1.请求转发:

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

java 复制代码
@Controller
public class EasyEController {
    @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";
    }
}

注意地址栏为localhost:8080/methoda,说明是先访问到methoda,在methoda下的方法中请求转发到了methodb,显示的是methodb中方法的内容

2.重定向:

可以在不同的服务之间跳转,浏览器发送两次请求,重定向是通过response对象通知浏览器重新访问 执行的是redirect方法

java 复制代码
@Controller
public class EasyEController {
    @RequestMapping("methoda")
    public String methodA(){
        System.out.println("----methodA");
        return "redirect:/methodb";
    }
    @RequestMapping("methodb")
    @ResponseBody
    public String methodB(){
        System.out.println("----methodB");
        return "this is methodb";
    }
}

注意此时的地址栏,我们访问的是 localhost:8080/methoda,但是访问后却变成了localhost:8080/methodb,说明在我们访问methoda时,我们的访问请求直接重定向到了methodb

4.SpringMVC 运行原理

我们的MVC,即Model View Controller,在下面的图中有体现

5.拦截器

拦截器(Interceptor)是 Spring MVC 提供的一种强大的功能组件。它可以对用户请求进行拦截,并在请求进入控制器(Controller)之前handler、控制器处理完请求后、甚至是渲染视图后,执行一些指定的操作。在 Spring MVC 中,拦截器主要用于拦截用户请求并做相应的处理,例如通过拦截器,我们可以执行权限验证、记录请求信息日志、判断用户是否已登录等操作。

java 复制代码
@Component
public class EasyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("----preHandle");
        return true;
    }

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

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("----afterCompletion--整个请求处理完毕");
    }
}
相关推荐
远望清一色6 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself15 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041520 分钟前
J2EE平台
java·java-ee
XiaoLeisj27 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man30 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*31 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家32 分钟前
go语言中package详解
开发语言·golang·xcode
llllinuuu32 分钟前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s33 分钟前
Golang--协程和管道
开发语言·后端·golang
王大锤439135 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang