开发简易版的AOP类

 1.定义了接口SmartAnimal 

package spring.aop;

/**
 * ClassName: SmartAnimal
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 21:02
 * @Version 1.0
 */
public interface SmartAnimal {
    public abstract Double getSum(double num1, double num2);//加法

    public abstract Double getSub(double num1, double num2);//减法
}

2.实现该接口,并重写接口的方法

package spring.aop;

/**
 * ClassName: TestCal1
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 21:03
 * @Version 1.0
 */
public class SmartAnimalTest implements SmartAnimal {
    @Override
    public Double getSum(double num1, double num2) {
        System.out.println("方法内部打印result=" + (num1 + num2));
        return num1 + num2;

    }

    @Override
    public Double getSub(double num1, double num2) {
        System.out.println("方法内部打印result=" + (num1 - num2));
        return num1 - num2;
    }
}

3.定义代理类,通过反射+动态代理 

package spring.aop;


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

/**
 * ClassName: VehicleProxyProvider
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 18:22
 * @Version 1.0
 */
public class SmartAnimalProxyProvider<T> {
    private T instance;//实现了T接口的对象实例

    public SmartAnimalProxyProvider(T instance) {
        this.instance = instance;//通过构造器初始化instance实例
    }


    /**
     * 得到的那个代理对象
     *
     * @param :
     * @return T
     * @author "卒迹"
     * @description TODO
     * @date 18:59
     */
    public T getProxy() {
        /**
         * 返回1个代理对象
         *
         * @param :
         * @return T
         * @author "卒迹"
         * @description TODO
         * @date 18:37
         */
        //参数1:类的加载器
        ClassLoader classLoader = instance.getClass().getClassLoader();
        //参数2:得到要代理的对象/被执行对象的接口信息
        Class<?>[] interfaces = instance.getClass().getInterfaces();
        //参数3: 调用处理器/对象 有1个非常重要的方法invoke
        //InvocationHandler是1个接口,使用匿名对象创建实现了该接口的对象实例
        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * @param proxy:  代理对象
             * @param method: 代理对象调用方法时的那个方法
             * @param args:   方法携带的参数
             * @return Object
             * @author "卒迹"
             * @description TODO
             * @date 18:53
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String methodName = method.getName() + "";
                System.out.println("日志-方法名-" + methodName + "-" + "参数" + args[0] + " " + args[1]);
                //通过反射调用该代理对象的方法,比如run方法
                // 参数1:代理对象instance     参数2:方法携带的参数
                Object invoke = method.invoke(instance, args);
                System.out.println("日志-方法名-" + methodName + "-" + "结果result=" + (Double)invoke);
                return invoke;
            }
        };
        return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}

4.调用测试方法 

package spring.aop;

/**
 * ClassName: CalTest
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 21:13
 * @Version 1.0
 */
public class CalTest {
    public static void main(String[] args) {
        //初始化代理对象
        //<SmartAnimal> 定义运算的接口
        //new SmartAnimalTest() 实现了SmartAnimal接口的对象实例
        SmartAnimalProxyProvider<SmartAnimal> smartAnimalSmartAnimalProxyProvider 
        	= new SmartAnimalProxyProvider<>(new SmartAnimalTest());
        //得到该代理对象
        SmartAnimal proxy = smartAnimalSmartAnimalProxyProvider.getProxy();
        proxy.getSum(10, 20);//调用代理对象的方法
        System.out.println("---------------------------------------------");
        proxy.getSub(10, 22);
    }
}

5.打印输出结果 

分析:以上代码存在什么问题? 

以上代码是写死在代理类中的,不利于复用和维护

解决方案:使用模板设计模式+动态绑定机制

package spring.aop;


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

/**
* ClassName: VehicleProxyProvider
* Package: spring.aop
* Description:
*
* @Author 王文福
* @Create 2024/2/1 18:22
* @Version 1.0
*/
public abstract class SmartAnimalProxyProvider<T> {
private T instance;//实现了T接口的对象实例

public SmartAnimalProxyProvider(T instance) {
    this.instance = instance;//通过构造器初始化instance实例
}

public abstract void init(Object proxy, Method method, Object[] args);//前置处理通知

public abstract void post(Object proxy, Method method, Object[] args, Object invoke);//后置处理通知

public abstract void exception(Exception e, Object proxy, Method method, Object[] args);//异常处理通知

public abstract void finallyDispose(Object proxy, Method method, Object[] args);//异常finally处理

/**
 * 得到的那个代理对象
 *
 * @param :
 * @return T
 * @author "卒迹"
 * @description TODO
 * @date 18:59
 */
public T getProxy() {
    /**
     * 返回1个代理对象
     *
     * @param :
     * @return T
     * @author "卒迹"
     * @description TODO
     * @date 18:37
     */
    //参数1:类的加载器
    ClassLoader classLoader = instance.getClass().getClassLoader();
    //参数2:得到要代理的对象/被执行对象的接口信息
    Class<?>[] interfaces = instance.getClass().getInterfaces();
    //参数3: 调用处理器/对象 有1个非常重要的方法invoke
    //InvocationHandler是1个接口,使用匿名对象创建实现了该接口的对象实例
    InvocationHandler invocationHandler = new InvocationHandler() {
        /**
         * @param proxy:  代理对象
         * @param method: 代理对象调用方法时的那个方法
         * @param args:   方法携带的参数
         * @return Object
         * @author "卒迹"
         * @description TODO
         * @date 18:53
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            try {
                init(proxy, method, args);//前置处理

                //通过反射调用该代理对象的方法,比如run方法
                // 参数1:代理对象instance     参数2:方法携带的参数
                Object invoke = method.invoke(instance, args);
                post(proxy, method, args, invoke);//后置处理
                return invoke;
            } catch (Exception e) {
                exception(e, proxy, method, args);//异常处理
                throw new RuntimeException(e);
            } finally {
                finallyDispose(proxy, method, args);//finally处理
            }
        }
    };
    return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
}

}

子类实现代理类的抽象方法(模板设计模式) 

package spring.aop;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * ClassName: SmartAnimalProxyProviderTest
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 22:34
 * @Version 1.0
 */
public class SmartAnimalProxyProviderTest extends SmartAnimalProxyProvider<SmartAnimal> {
    public SmartAnimalProxyProviderTest(SmartAnimal instance) {
        super(instance);
    }

    @Override
    public void init(Object proxy, Method method, Object[] args) {
        System.out.println("方法执行前-日志-方法名-" + method.getName() + "-参数 "
                + Arrays.asList(args)); //这里从AOP看,就是一个横切关注点-前置通知
    }

    @Override
    public void post(Object proxy, Method method, Object[] args, Object result) {
        System.out.println("方法执行正常结束-日志-方法名-" + method.getName() + "-结果result= "
                + result);//从AOP看, 也是一个横切关注点-返回通知
    }

    @Override
    public void exception(Exception e, Object proxy, Method method, Object[] args) {
        //如果反射执行方法时,出现异常,就会进入到catch{}
        System.out.println("方法执行异常-日志-方法名-" + method.getName()
                + "-异常类型=" + e.getClass().getName());//从AOP看, 也是一个横切关注点-异常通知
    }

    @Override
    public void finallyDispose(Object proxy, Method method, Object[] args) {
        //从AOP的角度看, 也是一个横切关注点-最终通知
        System.out.println("方法最终结束-日志-方法名-" + method.getName());
    }
}
package spring.aop;

import java.util.Objects;

/**
 * ClassName: CalTest
 * Package: spring.aop
 * Description:
 *
 * @Author 王文福
 * @Create 2024/2/1 21:13
 * @Version 1.0
 */
public class CalTest {
    public static void main(String[] args) {
        //初始化代理对象
        //<SmartAnimal> 定义运算的接口
        //new SmartAnimalTest() 实现了SmartAnimal接口的对象实例
        SmartDog smartDog = new SmartDog();
        //调用的是子类重写父类的抽象方法
        SmartAnimalProxyProvider smartAnimalProxyProvider = new SmartAnimalProxyProviderTest(smartDog);
        SmartAnimal proxy = (SmartAnimal) smartAnimalProxyProvider.getProxy();
        proxy.getSum(10,20);
        proxy.getSub(10,20);

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值