• 动态代理练习


    1.接口有实现类(有目标方法)

    package com.demo.demo;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    interface LogService{
        void doSave();
    }
    
    class LogServiceImpl implements LogService{//目标对象
        public void doSave() {
            System.out.println("save Log");
        }
    }
    
    class LogAspect{
        public void before(){//Aspect(切面)
            System.out.println("method before");
        }
        public void after(){
            System.out.println("method after");
        }
    }
    
    public class TestProxy01 {
        //在此类的对象方法中调用目标方法,添加业务扩展功能
        static class ServiceHandler implements InvocationHandler{
            private Object target;
            private LogAspect logAspect=new LogAspect();
            public ServiceHandler(Object target){
                this.target=target;
            }
            public Object invoke(Object proxy,
                    Method method, Object[] args) throws Throwable {
                //执行日志切面方法
                logAspect.before();
                //执行目标对象方法
                method.invoke(target, args);
                //执行日志切面方法
                logAspect.after();
                return null;
            }//整合核心业务调用与扩展业务调用
        }
        /**
         * 借助 JDK API(Proxy) 为目标对象创建动态代理对象
         * @param target
         * @return
         */
        static Object newLogServicePorxy(LogService target){
            LogService logService = (LogService)Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),    //loader 类的加载器
                    target.getClass().getInterfaces(),    //interfaces 目标对象实现的接口
                    new ServiceHandler(target));        //h 处理器,处理目标对象和 代理对象要织入扩展功能的业务的处理器
            return logService;
        }
    
        public static void main(String[] args) {
            LogService logService = (LogService) newLogServicePorxy(new LogServiceImpl());
            //当调用doSave方法时,系统底层会调用Handler对象的
            //invoke方法,执行核心业务与扩展业务的整合
            logService.doSave();
        }
    }

    2.接口没有实现类(即没有目标方法,仿照mybatis中的dao层)

    package com.demo.demo;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Map;
    
    interface FindDao{
        Map<String,String> findDao(Integer i);
    }
    
    class DemoProxy implements InvocationHandler{
        public static Object finds(Class<?> target) {
            Object obj = Proxy.newProxyInstance(
                    target.getClassLoader(), 
                    new Class[]{target}, 
                    new DemoProxy());
            return obj;
        }
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("do invoke!!!");
            return null;
        }
        
    }
    
    
    
    public class TestProxy03 {
        public static void main(String[] args) {
            FindDao f=(FindDao) DemoProxy.finds(FindDao.class);
            f.findDao(5);
        }
        
    }

    3.没有实现一个接口,直接就是一个类,需要使用CGLIB来做动态代理

    package com.demo.demo;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodProxy;
    //目标对象
    class HelloServiceImpl{
        public void sayHello(){
            System.out.println(" is ok !!! ");
        }
    }
    
    //如何借助CGLIB为如上对象创建一个代理对象
    //通过代理对象扩展    如上对象的扩展功能
    
    public class TestProxy04 {
        public static void main(String[] args) {
            //创建EnHancer对象(此对象为使用CGLIB入口对象)
            //要借助此对象为目标对象创建代理对象
            //这里的代理对象是目标对象的一个子类类型对象
            Enhancer h = new Enhancer();
            //设置代理对象要继承的那个父类的类型
            h.setSuperclass(HelloServiceImpl.class);
            //设置回调函数(当指定代理对象的方法时,会执行此Callback函数
            h.setCallback(new MethodInterceptor() {
                public Object intercept(
                        Object arg0,//指向代理对象
                        Method arg1,//目标对象的方法
                        Object[] arg2,//方法执行时实际参数
                        MethodProxy arg3//方法对象的代理
                        ) throws Throwable {
                    System.out.println("before do");
                    Object result = arg3.invokeSuper(arg0, arg2);
                    System.out.println("after do");
                    return result;
                }
            });//类似JDK动态代理的InvocationHandler
            
            Object obj = h.create();
            HelloServiceImpl hs = (HelloServiceImpl) obj;
            hs.sayHello();
        }
    }

    总结: AOP 底层基于代理机制实现功能扩展

      1.假如目标对象(被代理的对象)实现接口,则底层默认采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)

      2.假如目标对象(被代理对象)没有实现接口,则底层默认采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)

  • 相关阅读:
    tmux 鼠标滚动
    宝藏主题 cnblogsthemesilence
    数组乱序初始化:sorry, unimplemented: nontrivial designated initializers not supported
    SSH 连接 WSL
    移动硬盘变成 RAW 格式
    Linux 终端快捷键
    Adaptive AUTOSAR 学习笔记 1 概述、背景、AP CP 对比区别
    Qt扫盲篇
    Qt(C++)之实现风行播放器界面
    Qt之统一的UI界面格式基调,漂亮的UI界面
  • 原文地址:https://www.cnblogs.com/gxlaqj/p/11497150.html
Copyright © 2020-2023  润新知