zoukankan      html  css  js  c++  java
  • Jdk动态代理

    优点:代理可以对被代理对象通过一个invoke 方法对被代理的对象实行统一的处理。Spring AOP 实现
    缺点:只能对接口进行拦截
     
    同一个类中方法调用会导致被调用方法动态代理失败。和spring事务失效原因类似。
     
    // 服务提供者
    public interface Subject{
        void doSomething();
    }
     
    public class RealSubject implements Subject{
     
        @Override
        void  doSomething(){
            System.out.println("真实服务!");
        }    
    }
     
    public class ProxyHandler implements InvocationHandler {
     
        private Object proxied;
     
        public ProxyHandler(Object proxied) {
            this.proxied = proxied;
        }
     
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     
            //在转调具体目标对象之前,可以执行一些功能处理
            System.out.println("先干点");
            //转调具体目标对象的方法
     
            method.invoke( proxied, args);
     
            System.out.println("结束了,去喝酒");
            //在转调具体目标对象之后,可以执行一些功能处理
            return null;
        }
     
        public static void main(String[] args) {
            RealSubject real = new RealSubject();
            Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
                    new Class[]{Subject.class},
                    new ProxyHandler(real));
            proxySubject.doSomething();
            Method[] methods = proxySubject.getClass().getDeclaredMethods();
     
            Field[] fields = proxySubject.getClass().getDeclaredFields();
        }
        
    }
     
    //生成的代理类
    public class Proxy0 extends Proxy implements UserDao {
     
        //第一步, 生成构造器
        protected Proxy0(InvocationHandler h) {
            super(h);
        }
     
        //第二步, 生成静态域
        private static Method m1;   //hashCode方法
        private static Method m2;   //equals方法
        private static Method m3;   //toString方法
        private static Method m4;   //...
        
        //第三步, 生成代理方法
        @Override
        public int hashCode() {
            try {
                return (int) h.invoke(this, m1, null);
            } catch (Throwable e) {
                throw new UndeclaredThrowableException(e);
            }
        }
        
        @Override
        public boolean equals(Object obj) {
            try {
                Object[] args = new Object[] {obj};
                return (boolean) h.invoke(this, m2, args);
            } catch (Throwable e) {
                throw new UndeclaredThrowableException(e);
            }
        }
        
        @Override
        public String toString() {
            try {
                return (String) h.invoke(this, m3, null);
            } catch (Throwable e) {
                throw new UndeclaredThrowableException(e);
            }
        }
        
        @Override
        public void save(User user) {
            try {
                //构造参数数组, 如果有多个参数往后面添加就行了
                Object[] args = new Object[] {user};
                h.invoke(this, m4, args);
            } catch (Throwable e) {
                throw new UndeclaredThrowableException(e);
            }
        }
        
        //第四步, 生成静态初始化方法
        static {
            try {
                Class c1 = Class.forName(Object.class.getName());
                Class c2 = Class.forName(UserDao.class.getName());    
                m1 = c1.getMethod("hashCode", null);
                m2 = c1.getMethod("equals", new Class[]{Object.class});
                m3 = c1.getMethod("toString", null);
                m4 = c2.getMethod("save", new Class[]{User.class});
                //...
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
  • 相关阅读:
    selenium server在页面加载超时浏览器与driver通信失败时的妙用
    selenium并行的使用
    selenium代理
    selenium鼠标拖动
    做事要是专业
    selenium select 标签选中
    从字符串中提取数字
    selenium中Alter等弹出对话框的处理
    Selenium资料
    P2048 [NOI2010]超级钢琴 (RMQ,堆)
  • 原文地址:https://www.cnblogs.com/xzn-smy/p/9100153.html
Copyright © 2011-2022 走看看