• 结构型之代理模式


    序言

      代理模式可以实现对被代理对象的间接控制,可以对被代理对象的方法进行增强,她不重写原有的方法。
    代理模式基本分为3类:

    1. jdk静态代理: 1个代理类只能代理1个类,局限性较大。
    2. jdk动态代理: 1个代理类能代理多个类,要求被代理类必须要有接口,利用了反射,效率比较低。
    3. cglib动态代理:1个代理类能代理多个类,被代理类不需要有接口,效率较高,不能代理final的类和方法

    1. jdk静态代理模式

    套路:

    1. 代理类要实现被代理类的接口,使代理类的方法与被代理类的保持一致。
    2. 代理类要加入一个被代理类的委托对象,由客户端初始化。
    3. 添加私有的增强方法。
    /**
     * 登录接口
     */
    public interface LoginService {
        public void login();
    }
    
    /**
     * 登录接口代理对象
     */
    public class LoginServiceProxy implements LoginService{
        private LoginService loginService;
    
        public LoginServiceProxy(LoginService loginService){
            this.loginService = loginService;
        }
        public void login() {
            preLogin();
            loginService.login();
            postLogin();
        }
        private void preLogin(){
            System.out.println("=====登录前认证校验=====");
        }
        private void postLogin(){
            System.out.println("=====登录后日志记录=====");
        }
    
    }
    
    /**
     * 登录接口实现类
     */
    public class LoginServiceImpl implements LoginService{
        public void login() {
            System.out.println("正在登录...");
        }
    }
    
    /**
     * jdk静态代理测试
     */
    public class JdkStaticProxyTest {
    
        @Test
        public void testJdkStaticProxy(){
            LoginServiceProxy loginServiceProxy = new LoginServiceProxy(new LoginServiceImpl());
            loginServiceProxy.login();
        }
    }
    

    2. jdk动态代理模式

    /**
     * 登录接口
     */
    public interface LoginService {
        public void login();
    }
    
    /**
     * 登录接口实现类
     */
    public class LoginServiceImpl implements LoginService {
        public void login() {
            System.out.println("正在登录...");
        }
    }
    
    /**
     * 登录接口代理对象
     */
    public class ServiceInvocationHandler implements InvocationHandler {
    
        //被代理对象
        private Object target;
    
        public ServiceInvocationHandler(Object object){
            this.target = object;
        }
    
        private void preOperation(){
            System.out.println("=====执行前校验=====");
        }
        private void postOperation(){
            System.out.println("=====执行后记录日志=====");
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            preOperation();
            Object result = method.invoke(target, args);
            postOperation();
            return result;
        }
    
        public Object getProxy() throws Throwable {
    
            return Proxy.newProxyInstance(Thread.currentThread()
                    .getContextClassLoader(), this.target.getClass()
                    .getInterfaces(), this);
        }
    }
    
    /**
     * jdk静态代理测试
     */
    public class JdkDynamicProxyTest {
    
        @Test
        public void testJdkStaticProxy() throws Throwable {
            LoginService proxy = (LoginService) new ServiceInvocationHandler(new LoginServiceImpl()).getProxy();
            proxy.login();
            System.out.println(proxy.getClass());
        }
    }
    

    3. cglib动态代理模式

    /**
     * 登录类
     */
    public class LoginServiceImpl{
        public void login() {
            System.out.println("正在登录...");
        }
    }
    
    /**
     * 登录接口代理对象
     */
    public class LoginServiceProxy implements MethodInterceptor{
    
        private Object target;
    
        public LoginServiceProxy(Object obj){
            this.target = obj;
        }
    
        public Object getInstance(){
    
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.target.getClass());
            enhancer.setCallback(this); //设置回调方法
            return enhancer.create(); //创建代理对象
        }
    
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            preOpteration();
            Object result = methodProxy.invokeSuper(o, objects);
            postOpteration();
            return result;
        }
    
        private void preOpteration(){
            System.out.println("=====执行前校验=====");
        }
        private void postOpteration(){
            System.out.println("=====执行后记录日志=====");
        }
    
    }
    
    /**
     * cglib动态代理测试
     */
    public class CglibProxyTest {
        
        @Test
        public void testCglibProxy(){
            LoginServiceImpl loginServiceProxy = (LoginServiceImpl) new LoginServiceProxy(new LoginServiceImpl()).getInstance();
            loginServiceProxy.login();
        }
    }
    
    

    后记

  • 相关阅读:
    论url
    jquery send(data) 对data的处理
    jquery ajax 对异步队列defer与XMLHttprequest.onload的依赖
    requirejs解决异步模块加载方案
    vue 解决display与 transition冲突
    node exports与 module.exports的区别
    node js 模块分类
    写在入职初期
    入职前要学习的一些知识
    论文实验 云平台压力测试及服务器性能测试
  • 原文地址:https://www.cnblogs.com/codebug/p/7339899.html
Copyright © 2020-2023  润新知