代理模式:
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象
静态代理模式
思想:
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
思路:USB公共接口有目标对象实现方法save目标对象具有了可以保存对象的功能,为了扩展其目标对象的功能,创建一个代理对象,在进行对象的功能扩展时(在不进行修改对象代码的情况下进行扩展),代理对象实现目标对象所实现的接口,在代理对象实现的接口类通过代理对象的构造器进行传递目标对象,然后在代理对象的实现方法内部进行扩展所需要扩展的功能,然后调用所传递的对象的原始方法。
代码实现:
/**
*
*
* @version 创建时间:2019年3月1日 上午8:16:07
*
* 类说明 :USB接口类,通过实现接口才能实现数据的传输保存
*
*/
public interface USB {
void save();
}
* @author Wang :
*
* @version 创建时间:2019年3月1日 上午8:17:14
*
* 类说明 :用户实现接口去传输数据
*
*/
public class User implements USB {
@Override
public void save() {
System.out.println("----数据的储存----");
}
}
package com.myjava.proxy.staticproxy;
/**
*
* @author Wang Junyong:
*
* @version 创建时间:2019年3月1日 上午8:18:33
*
* 类说明 :代理对象,进行代理数据的储存
*
*/
public class DataSaveProxy implements USB {
// 接收保存目标对象
private User targetuser;
public DataSaveProxy(User targetuser) {
this.targetuser = targetuser;
}
@Override
public void save() {
System.out.println("-----额外的方法执行-----");
// 执行目标对象的方法
targetuser.save();
}
}
* @author Wang Junyong:
*
* @version 创建时间:2019年3月1日 上午8:22:15
*
* 类说明 :测试类
*
*/
public class Test {
public static void main(String[] args) {
// 创建目标对象
User user = new User();
// 创建代理对象
DataSaveProxy proxy = new DataSaveProxy(user);
// 调用代理对象的方法,进行代理执行
proxy.save();
}
}
动态代理模式
动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理
代码分析:JDK中生成代理对象的API
代理类所在包:java.lang.reflect.Proxy
JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,完整的写法是:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入。
代码实现:
package com.myjava.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* @author Wang :
*
* @version 创建时间:2019年3月1日 上午8:30:09
*
* 类说明 :动态理工厂类,动态代理不需要实现接口,但需要指定接口类型
*
*/
public class FactoryProxy {
// 维护一个目标对象
private Object targetObject;
public FactoryProxy(Object targetObject) {
this.targetObject = targetObject;
}
// 给目标对象生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
targetObject.getClass().getClassLoader(), // 获取目标对象的类加载器
targetObject.getClass().getInterfaces(), // 获取 目标对象的接口
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object = method.invoke(targetObject, args);
return object;
}
});
}
}
* @version 创建时间:2019年3月1日 上午8:37:17
*
* 类说明 :测试动态代理对象
*
*/
public class Test {
public static void main(String[] args) {
// 创建目标对象
User user = new User();
// 给目标对象创建代理对象
Object object = new FactoryProxy(user).getProxyInstance();
USB proxy = (USB) object;
// 执行方法
proxy.save();
}
}