String Aop 动态代理例子

动态代理原理:spring AOP采用动态代理来实现

(1)定义一个接口Boy

package aop001;

public interface Boy {
    public void beat(String time);
    
    public void play(String time);
}

(2)定义两个类实现Boy接口:

Boy_1

package aop001;

public class Boy_1 implements Boy {

    @Override
    public void beat(String time) {
        System.out.println("我是boy1");
        System.out.println(time+"敲代码");
    }

    @Override
    public void play(String time) {
        System.out.println("我是boy1");
        System.out.println(time+"玩游戏");
    }

}

Boy_2

package aop001;

public class Boy_2 implements Boy{

    @Override
    public void beat(String time) {
        System.out.println("我是boy2");
        System.out.println(time+"敲代码");
    }

    @Override
    public void play(String time) {
        System.out.println("我是boy2");
        System.out.println(time+"玩游戏");
    }

}

(3)定义一个动态代理类并实现InvocationHandler接口

package aop001;

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

public class BoyInvocationHandler implements InvocationHandler {
    //定义一个Object对象,保存目标
    private Object targer;// 目标是不固定
    
    //添加构造方法,可以通过构造方法给target赋值
    public BoyInvocationHandler(Object targer) {
        this.targer = targer;
    }
    
    //非核心业务的代码由动态代理来管理
    //定义一个前置任务的方法
    private void before(){
        // 前置任务
        System.out.println("[代理执行前置]起床");
        System.out.println("[代理执行前置]刷牙洗脸");
        System.out.println("[代理执行前置]吃饭");
        System.out.println("*****************");
    }
    
    //定义一个后置任务的方法
    private void after(){
        // 后置任务
        System.out.println("*****************");
        System.out.println("[代理执行后置]洗澡");
        System.out.println("[代理执行后置]睡觉");
        System.out.println("");
    }
    
    //调用invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //调用前置任务的方法
        before();
        //获取类里面的方法的返回值
        Object returnValue=method.invoke(targer, args);
        //调用后置任务的方法
        after();
        
        return returnValue;
    }
    
    
    

}

(4)新建一个Test测试类

package aop001;

import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args) {
        //第一步:创建目标实现类的实例
        Boy b1=new Boy_1();
        Boy b2=new Boy_2();
                
        //第二步:创建一个动态代理类(CEO 首席执行官)
        BoyInvocationHandler handler1 = new BoyInvocationHandler(b1);
        BoyInvocationHandler handler2 = new BoyInvocationHandler(b2);
        
        //第三步:创建动态代理(跟静态代理一样,申明的变量仍然是目标的接口)
        Boy girlProxy1 = (Boy) Proxy.newProxyInstance(
                                    b1.getClass().getClassLoader(),
                                    b1.getClass().getInterfaces(),
                                    handler1);
        //调用方法
        girlProxy1.beat("周六"); 
        girlProxy1.play("周日");
        
        Boy girlProxy2 = (Boy) Proxy.newProxyInstance(
                                    b2.getClass().getClassLoader(),
                                    b2.getClass().getInterfaces(),
                                    handler2);
        girlProxy2.beat("周六"); 
        girlProxy2.play("周日");
        
    }

}

(5)运行结果:

[代理执行前置]起床
[代理执行前置]刷牙洗脸
[代理执行前置]吃饭
*****************
我是boy1
周六敲代码
*****************
[代理执行后置]洗澡
[代理执行后置]睡觉

[代理执行前置]起床
[代理执行前置]刷牙洗脸
[代理执行前置]吃饭
*****************
我是boy1
周日玩游戏
*****************
[代理执行后置]洗澡
[代理执行后置]睡觉

[代理执行前置]起床
[代理执行前置]刷牙洗脸
[代理执行前置]吃饭
*****************
我是boy2
周六敲代码
*****************
[代理执行后置]洗澡
[代理执行后置]睡觉

[代理执行前置]起床
[代理执行前置]刷牙洗脸
[代理执行前置]吃饭
*****************
我是boy2
周日玩游戏
*****************
[代理执行后置]洗澡
[代理执行后置]睡觉

(6)当我们需要更改非核心代码时,我们只要更改一处就可以了。

谢谢!

原文地址:https://www.cnblogs.com/qq1272850043/p/5868639.html