设为首页 加入收藏

TOP

day08-AOP-01(一)
2023-07-25 21:43:03 】 浏览:47
Tags:day08-AOP-01

AOP

1.官方文档

AOP讲解:下载的spring文件-->spring-framework-5.3.8/docs/reference/html/core.html#aop

AOP APIs:下载的spring文件-->spring-framework-5.3.8/docs/reference/html/core.html#aop-api

2.动态代理

2.1案例说明

需求说明:

  1. 有Vehicle(交通工具接口,有一个run方法),下面有两个实现类Car,Ship

  2. 当运行Car对象的run()方法和Ship对象的run()方法时,输出如下内容,注意观察前后有统一的输出

    image-20230123170808933 image-20230123170808933
  3. 请思考如何完成?

2.2传统方式解决

Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 * 接口,定义了run方法
 */
public interface Vehicle {
    public void run();
}

Ship类,实现Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Ship implements Vehicle {

    @Override
    public void run() {
        System.out.println("交通工具开始运行了...");
        System.out.println("大轮船在水上 running...");
        System.out.println("交通工具停止运行了...");
    }
}

Car类,实现Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("交通工具开始运行了...");
        System.out.println("小汽车在公路 running...");
        System.out.println("交通工具停止运行了...");
    }
}

TestVehicle测试类:

package com.li.proxy;

import org.testng.annotations.Test;

/**
 * @author 李
 * @version 1.0
 */
public class TestVehicle {
    @Test
    public void run() {
        Vehicle vehicle = new Car();//Vehicle vehicle = new Ship();
        vehicle.run();//动态绑定,根据实际运行类型调用run方法
    }
}
image-20230123173613218

上面的方式,代码冗余,其实就是单个对象的调用,并没有很好的解决问题。

2.3动态代理方式解决

解决思路:在调用方法的时候,使用反射机制,根据方法去决定调用哪个对象方法

Vehicle接口不变:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 * 接口,定义了run方法
 */
public interface Vehicle {
    public void run();
}

Ship:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Ship implements Vehicle {

    @Override
    public void run() {
        System.out.println("大轮船在水上 running...");
    }
}

Car:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("小汽车在公路 running...");
    }
}

创建VehicleProxyProvider,该类返回一个代理对象:

package com.li.proxy;

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

/**
 * @author 李
 * @version 1.0
 * VehicleProxyProvider类可以返回一个代理对象
 */
public class VehicleProxyProvider {
    //定义一个属性
    //target_vehicle 表示真正要执行的对象
    //要求该对象的类实现了Vehicle接口
    private Vehicle target_vehicle;

    //构造器
    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }


    //编写一个方法,可以返回一个代理对象
    public Vehicle getProxy() {
        //(1)得到类加载器
        ClassLoader classLoader =
                target_vehicle.getClass().getClassLoader();

        //(2)得到要代理的对象/被执行的对象 的接口信息,底层通过接口来完成调用
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();

        //(3)创建一个调用处理对象
        /**
         *   public interface InvocationHandler {
         *      public Object invoke(Object proxy, Method method, Object[] args)
         *      throws Throwable;
         *   }
         *   invoke 方法在将来执行我们的 target_vehicle的方法时,会调用到
         */
        //如上,因为InvocationHandler是接口,不能直接实例化
        // 以匿名内部类的方式来获取 InvocationHandler 对象
        //这个对象有一个方法:invoke, 到时可以通过反射,动态调用目标对象的方法
        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * invoke()方法,在将来执行我们的target_vehicle的方法时会调用到
             * @param proxy 表示代理对象
             * @param method 就是通过代理对象调用方法时,的哪个方法
             * @param args 表示调用代理对象的方法时,传入方法的参数
             * @return 表示代理对象.方法(xx) 执行后的结果
             * @throws Throwable
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇推荐一个分布式单点登录框架XXL-S.. 下一篇读函数式编程思维笔记05_现实应用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目