IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Spring的AOP前奏

第一章 AOP前奏

1.1 代理模式
  • 代理模式:我们需要做一件事情,又不期望自己亲力亲为,此时,可以找一个代理【中介】

  • 我们【目标对象】与中介【代理对象】不能相互转换,因为是"兄弟"关系

1.2 为什么需要代理【程序中】
  • 需求:实现【加减乘除】计算器类

    • 在加减乘除方法中,添加日志功能【在计算之前,记录日志。在计算之后,显示结果。】
  • 实现后发现问题如下

    • 日志代码比较分散,可以提取日志类
    • 日志代码比较混乱,日志代码【非核心业务代码】与加减乘除方法【核心业务代码】书写一处
  • 总结:在核心业务代码中,需要添加日志功能,但不期望在核心业务代码中书写日志代码

    • 此时:使用代理模式解决问题【先将日志代码横向提取到日志类中,再动态织入回到业务代码中
1.3 手动实现动态代理环境搭建
  • 实现方式

    • 基于接口实现动态代理: JDK动态代理
    • 基于继承实现动态代理: Cglib、Javassist动态代理
  • 实现动态代理关键步骤

    • 一个类:Proxy
      • 概述:Proxy代理类的基类【类似Object】
      • 作用:newProxyInstance():创建代理对象
    • 一个接口:InvocationHandler
      • 概述:实现【动态织入效果】关键接口
      • 作用:invoke(),执行invoke()实现动态织入效果
1.4 手动实现动态代理关键步骤

注意:代理对象与实现类【目标对象】是"兄弟"关系,不能相互转换

  • 创建类【为了实现创建代理对象工具类】
  • 提供属性【目标对象:实现类】
  • 提供方法【创建代理对象】
  • 提供有参构造器【避免目标对为空】
java 复制代码
package com.atguigu.beforeaop;

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

/**
 * @author Chunsheng Zhang 尚硅谷
 * @create 2022/3/28 16:22
 */
public class MyProxy {

    /**
     * 目标对象【目标客户】
     */
    private Object target;

    public MyProxy(Object target){
        this.target = target;
    }

    /**
     * 获取目标对象的,代理对象
     * @return
     */
    public Object getProxyObject(){
        Object proxyObj = null;

        /**
            类加载器【ClassLoader loader】,目标对象类加载器
            目标对象实现接口:Class<?>[] interfaces,目标对象实现所有接口
            InvocationHandler h
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //创建代理对象
        proxyObj = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            //执行invoke()实现动态织入效果
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //获取方法名【目标对象】
                String methodName = method.getName();
                //执行目标方法之前,添加日志
                MyLogging.beforeMethod(methodName,args);
                //触发目标对象目标方法
                Object rs = method.invoke(target, args);
                //执行目标方法之后,添加日志
                MyLogging.afterMethod(methodName,rs);
                return rs;
            }
        });
        return proxyObj;
    }

//    class invocationImpl implements InvocationHandler{
//    }

}
java 复制代码
@Test
    public void testBeforeAop(){

//        int add = calc.add(1, 2);
//        System.out.println("add = " + add);

        //目标对象
        Calc calc = new CalcImpl();
        //代理工具类
        MyProxy myProxy = new MyProxy(calc);
        //获取代理对象
        Calc calcProxy = (Calc)myProxy.getProxyObject();
        //测试
//        int add = calcProxy.add(1, 2);
        int div = calcProxy.div(2, 1);

    }
相关推荐
cyt涛2 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Jason不在家3 小时前
Flink 本地 idea 调试开启 WebUI
大数据·flink·intellij-idea
菜鸟一皓3 小时前
IDEA的lombok插件不生效了?!!
java·ide·intellij-idea
OLDERHARD6 小时前
Java - MyBatis(上)
java·oracle·mybatis
CS_GaoMing14 小时前
Centos7 JDK 多版本管理与 Maven 构建问题和注意!
java·开发语言·maven·centos7·java多版本
Java探秘者15 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
秋夫人15 小时前
idea 同一个项目不同模块如何设置不同的jdk版本
java·开发语言·intellij-idea
计算机学姐18 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
我是浮夸20 小时前
MyBatisPlus——学习笔记
java·spring boot·mybatis
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑21 小时前
JavaWeb(二)
java·数据仓库·hive·hadoop·maven