结构型模式 --- 代理模式

2020-03-17  本文已影响0人  十二找十三
访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介


代理模式的主要优点有:
    代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用
    代理对象可以扩展目标对象的功能
    代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度


其主要缺点是:
    在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
    增加了系统的复杂度


代理模式有不同的形式 主要有3种 静态代理  动态代理(jdk代理) Cglib代理(可以在内存中动态的实现 而不需要实现接口)
1.静态代理

// 定义接口类
package proxy.staticproxy;

public interface TeacherDao {
    void teach();
}



// 定义实现类
package proxy.staticproxy;

public class TeacherDaoImpl implements TeacherDao{

    @Override
    public void teach() {
        System.out.println("you are useing teacherDaoImpl teach method.");
    }

}


// 代理类
package proxy.staticproxy;

public class TeacherDaoImplStaticProxy implements TeacherDao{
    
    private TeacherDao target;
    
    
    public TeacherDaoImplStaticProxy(TeacherDao teacherDaoImpl) {
        this.target = teacherDaoImpl;
    }

    @Override
    public void teach() {
        System.out.println("before");
        target.teach();
        System.out.println("after");
    }

}


// 测试 调用
package proxy.staticproxy;

public class Client {
    public static void main(String[] args) {
        
        TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();
        
        TeacherDaoImplStaticProxy proxy = new TeacherDaoImplStaticProxy(teacherDaoImpl);
            
        proxy.teach();
    }
}

2.动态代理

// 定义接口
package proxy.dynamicproxy;

public interface TeacherDao {
    void teach();
}


// 定义实现类
package proxy.dynamicproxy;

public class TeacherDaoImpl implements TeacherDao{

    @Override
    public void teach() {
        System.out.println("you are useing teacherDaoImpl teach method.");
    }

}

// 代理类
package proxy.dynamicproxy;

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

public class ProxyFactory {
    private Object target;
    
    public ProxyFactory(Object target) {
        this.target = target;
    }
    
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                
                System.out.println("before");
                Object returnValue = method.invoke(target, args);
                System.out.println("after");
                return returnValue;
            }
        });
    }
    
}


// 测试类
package proxy.dynamicproxy;

public class Client {
    public static void main(String[] args) {
        TeacherDao target = new TeacherDaoImpl();

        TeacherDao proxyTeacherDaoImpl = (TeacherDao) new ProxyFactory(target).getProxyInstance();

        proxyTeacherDaoImpl.teach();

    }
}

3.cglib动态代理 需要引用下面的jar包
asm-7.3.1.jar
asm-commons-7.3.1.jar
asm-tree-7.3.1.jar
cglib-3.3.0.jar

// 接口类
package proxy.cglib;

public class TeacherDao {
    void teach() {
        System.out.println("teach method!");
    }
}

// 代理类
package proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyFactory implements MethodInterceptor{
    
    private Object target;
    
        
    public ProxyFactory(Object target) {
        this.target = target;
    }
    
    // 返回一个代理对象 是target对象的代理对象
    public Object getProxyInstance() {
        // 1.创建一个工具类
        Enhancer enhancer = new Enhancer();
        
        // 2.设置父类
        enhancer.setSuperclass(target.getClass());
        
        // 3.设置回调函数
        enhancer.setCallback(this);
        
        // 4.创建子类对象 即代理对象
        return enhancer.create();
    }
    
    
    
    @Override
    public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
        System.out.println("cglib 代理模式 before");
        
        Object returnValue = method.invoke(target, arg2);
            
        System.out.println("cglib 代理模式 after");
        return returnValue;
    }

}

// 测试类
package proxy.cglib;

public class Client {
    public static void main(String[] args) {
        TeacherDao target = new TeacherDao();
        
        
        TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(target).getProxyInstance();
        
        
        proxyInstance.teach();
    }
}

上一篇下一篇

猜你喜欢

热点阅读