• 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)当我们需要更改非核心代码时,我们只要更改一处就可以了。

    谢谢!

  • 相关阅读:
    远程调用之RMI、Hessian、Burlap、Httpinvoker、WebService的比较
    遍历List/Map的时候删除成员遇到的奇怪问题
    Java事务处理
    ThreadLocal学习记录
    IntelliJ IDEA+Tomcat+Nginx运行git项目
    JavaIO和JavaNIO
    Spring MVC的启动过程
    Java中的集合类
    Java中的泛型
    Java 多线程的基本概念
  • 原文地址:https://www.cnblogs.com/qq1272850043/p/5868639.html
Copyright © 2020-2023  润新知