博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式——代理模式

Posted on 2019-12-27 21:35  心默默言  阅读(163)  评论(0编辑  收藏  举报

1.为什么要使用代理

 

2.静态代理

2.1概念

 

2.2代码实现

1.定义业务接口

package com.bj.service;

//本代理的接口将要被增强
public interface ISomeService {
    String doFirst();
    void doSecond();
}

2.定义目标类,该类实现了业务接口

package com.bj.service;

//代理类将要增强的类
public class SomeServiceImpl implements ISomeService {

    @Override
    public String doFirst() {
        System.out.println("执行doFirst方法");
        return "abcd";
    }

    @Override
    public void doSecond() {
        System.out.println("执行doSecond方法");
    }

}

3.定义代理类

这个类要实现ISomeService接口,并且该代理类要讲接口对象作为一个成员变量,还要定义一个带餐的构造器,这个参数为接口对象。目的是将目标对象引入代理类,以便代理类调用目标类的方法。

package com.bj.proxy;

import com.bj.service.ISomeService;

public class ServiceProxy implements ISomeService {

    private ISomeService target;

    public ServiceProxy() { // Source快捷键:alt+shift+s + c

    }

    public ServiceProxy(ISomeService target) {
        this.target = target;
    }

    @Override
    public String doFirst() {
        String result = target.doFirst();
        // 增强:将目标方法返回的全小写字母,转化为全大写
        return result.toUpperCase();
    }

    @Override
    public void doSecond() {
        target.doSecond();
    }

}

4.测试

package com.bj.test;

import com.bj.proxy.ServiceProxy;
import com.bj.service.ISomeService;
import com.bj.service.SomeServiceImpl;

public class MyTest {

    public static void main(String[] args) {
        ISomeService target = new SomeServiceImpl();
        ISomeService service = new ServiceProxy(target); // rename:alt+shift+r
        String result = service.doFirst();
        System.out.println(result);
        service.doSecond();
    }
}

3.JDK动态代理

3.1概念

 

 

 

 

 

 

3.2代码

 

1.定义业务接口ISomeService

package com.bj.service;

//本代理的接口将要被增强
public interface ISomeService {
    String doFirst();
    void doSecond();
}

2.定义目标类ISomeServiceImpl

package com.bj.service;

//代理类将要增强的类
public class SomeServiceImpl implements ISomeService {

    @Override
    public String doFirst() {
        System.out.println("执行doFirst方法");
        return "abcd";
    }

    @Override
    public void doSecond() {
        System.out.println("执行doSecond方法");
    }

}

以上两个步骤与静态代理类中代码相同。

3.测试类

package com.bj.test;

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

import com.bj.service.ISomeService;
import com.bj.service.SomeServiceImpl;

public class MyTest {

    public static void main(String[] args) {
        ISomeService target = new SomeServiceImpl();
        // 由proxy类的newProxyInstance方法生成的一个动态代理对象
        ISomeService service = (ISomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 目标类的类加载器
                target.getClass().getInterfaces(), // 目标类所实现的所有接口
                new InvocationHandler() { // 目标类的匿名内部类

                    // proxy:代理对象
                    // method:目标方法
                    // args:目标方法的参数列表
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = method.invoke(target, args);
                        if (result!=null) { //添加if的快捷键:alt+shift+z,3
                            result = ((String) result).toUpperCase(); //抽取一个变量的快捷键 ctrl+shift+l
                        }
                        return result;
                    }
                }); // rename:alt+shift+r
        String result = service.doFirst();
        System.out.println(result);
         service.doSecond();
    }
}

4.CGLIB动态代理

4.1概念

 

 

 

4.2代码实现

1.导入jar包

 

 

2.定义目标类,注意不用实现任何接口

package com.bj.service;

//目标类:没有实现任何接口
public class SomeService  {

    public String doFirst() {
        System.out.println("执行doFirst方法");
        return "abcd";
    }

    public void doSecond() {
        System.out.println("执行doSecond方法");
    }

}

3.创建代理类的工厂。该类要实现MethodIntercept接口

package com.bj.factory;

import java.lang.reflect.Method;

import com.bj.service.SomeService;

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


//注意:使用cglib动态代理,要求目标类不能是final的
//因为final类是不能有子类的,而cglib动态代理增强的原理是:子类增强父类
public class CglibFactory implements MethodInterceptor {
    private SomeService target; //1.声明目标类的成员变量,并创建以目标类为参数的构造器,用于接收目标对象
    
    public CglibFactory() {
        
    }
    
    public CglibFactory(SomeService target) {
        this.target = target;
    }

    public SomeService myCglibCreator() { //2.定义代理类的生成方法,用于创建代理对象
        Enhancer enhancer = new Enhancer(); 
        //指定父类,即目标类。因为cglib动态代理增强的原理是:子类增强父类
        enhancer.setSuperclass(SomeService.class);
        //设置回调接口对象
        enhancer.setCallback(this);
        //create()方法用于创建cglib动态代理对象方法,即目标类的子类对象
        return (SomeService) enhancer.create();
        
    }
    //回调接口的方法
    @Override //3.定义回调接口方法。对目标类的增强在这里完成
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Object invoke = method.invoke(target, args);
        if (invoke!=null) {//添加if的快捷键:alt+shift+z,3
            invoke = ((String) invoke).toUpperCase();
        }
        return invoke;
    }

}

4.测试

package com.bj.test;

import com.bj.factory.CglibFactory;
import com.bj.service.SomeService;

public class MyTest {

    public static void main(String[] args) {
        SomeService target = new SomeService();
        SomeService service = new CglibFactory(target).myCglibCreator();
        String result = service.doFirst();
        System.out.println(result);
         service.doSecond();
    }
}