山西做网站,高米店网站建设,wordpress数据库修改域名,无网站做cpa0、前言
代理模式可以在不修改被代理对象的基础上#xff0c;通过扩展代理类#xff0c;进行一些功能的附加与增强。
1、静态代理 静态代理是一种代理模式的实现方式#xff0c;它在编译期间就已经确定了代理对象#xff0c;需要为每一个被代理对象创建一个代理类。静态代…0、前言
代理模式可以在不修改被代理对象的基础上通过扩展代理类进行一些功能的附加与增强。
1、静态代理 静态代理是一种代理模式的实现方式它在编译期间就已经确定了代理对象需要为每一个被代理对象创建一个代理类。静态代理的实现比较简单但是每个被代理对象都需要创建一个代理类因此在代理对象比较多时会导致代码几余和维护成本增加。 静态代理有两种实现继承和聚合两种模式。
1.1、继承模式 需要定义接口或者父类被代理对象与代理对象一起实现相同的接口或者继续相同父类代理对象继承目标对象重新目标对象的方法。 目标对象
package proxy.staticproxy.extends_model;//目标对象
public class UserService {public void login(){System.out.println(login success);}
}代理类
package proxy.staticproxy.extends_model;//代理对象
public class UserServiceProxy extends UserService{public void login(){System.out.println(开始执行--------------);super.login();}
} 测试类
package proxy.staticproxy;import proxy.staticproxy.extends_model.UserServiceProxy;
import proxy.staticproxy.implements_model.FactoryOne;
import proxy.staticproxy.implements_model.FactoryOneProxy;
import proxy.staticproxy.implements_model.IFactory;public class Test {org.junit.Testpublic void extends_model(){UserServiceProxy proxy new UserServiceProxy();proxy.login();}// 待代理类来处理/// 场景当不想改动被代理类的业务逻辑在处理开始和结束分别加上时间显示/// 处理核心逻辑需要实现被代理类的接口及方法在实现方法中田间需要添加的业务处理逻辑org.junit.Testpublic void implements_model(){// 创建被代理类的对象IFactory word new FactoryOne();// 创建代理类的对象IFactory proxyPaperFactory new FactoryOneProxy(word);proxyPaperFactory.production();}// 直接调用被代理类业务处理org.junit.Testpublic void test01(){// 创建被代理类的对象IFactory word new FactoryOne();word.production();}
}执行结果
开始执行--------------
login success
1.2、聚合模式 Subject抽象主题角色抽象主题类可以是抽象类也可以是接口是一个最普通的业务类型定义无特殊要求。RealSubject具体主题角色也叫被委托角色、被代理角色。是业务逻辑的具体执行者。Proxy代理主题角色也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现并且在具体主题角色处理完毕前后做预处理和善后工作。
Subject 接口
package proxy.staticproxy.implements_model;public interface IFactory {void production();
}RealSubject 类
package proxy.staticproxy.implements_model;public class FactoryOne implements IFactory {Overridepublic void production() {System.out.println( 被代理类开始初始化 );System.out.println( 生产笔记本、鼠标、键盘等等 );System.out.println( 被代理类处理完成 );}
}Proxy 类
package proxy.staticproxy.implements_model;public class FactoryOneProxy implements IFactory {private IFactory factory; // 用被代理类对象进行实例化public FactoryOneProxy(IFactory factory) {this.factory factory;}Overridepublic void production() {System.out.println( 代理开始工作 ,在此可以添加处理逻辑);factory.production();System.out.println( 代理结束工作 在此可以添加处理逻辑);}
}测试类
package proxy.staticproxy;import proxy.staticproxy.extends_model.UserServiceProxy;
import proxy.staticproxy.implements_model.FactoryOne;
import proxy.staticproxy.implements_model.FactoryOneProxy;
import proxy.staticproxy.implements_model.IFactory;public class Test {org.junit.Testpublic void extends_model(){UserServiceProxy proxy new UserServiceProxy();proxy.login();}// 待代理类来处理/// 场景当不想改动被代理类的业务逻辑在处理开始和结束分别加上时间显示/// 处理核心逻辑需要实现被代理类的接口及方法在实现方法中田间需要添加的业务处理逻辑org.junit.Testpublic void implements_model(){// 创建被代理类的对象IFactory word new FactoryOne();// 创建代理类的对象IFactory proxyPaperFactory new FactoryOneProxy(word);proxyPaperFactory.production();}// 直接调用被代理类业务处理org.junit.Testpublic void test01(){// 创建被代理类的对象IFactory word new FactoryOne();word.production();}
}运行结果 代理开始工作 ,在此可以添加处理逻辑被代理类开始初始化 生产笔记本、鼠标、键盘等等 被代理类处理完成 代理结束工作 在此可以添加处理逻辑
2、动态代理 动态代理是一种代理模式的实现方式它在运行期间根据需要动态生成代理对象无需手动编写代理类可以减少代码几余和维护成本。动态代理适用于需要代理的对象数量较多代理类实现对灵活的场景例Spring框架中的Spring AOP(面向切面编程)功能。 动态代理的实现方式也有两种JDK动态代理和CGLB动态代理两种模式。本文重点介绍JDK动态代理 在JDK中有一个Proxy类名词代理人。Proxy类是专门完成代理的操作类可以通过此类为一个或多个接口动态的生成实现类。Proxy类提供的有一个静态方法newProxyInstance()方法给我们的目标对象委托对象返回一个代理对象。 核心方法newProxyInstance方法的三个参数按照顺序分别是 ClassLoader 类加载器interfaces(一组接口接口数组)InvocationHandler调用处理器。
ClassLoader 类加载器
定义了由哪个classLoader对象来对生成的代理对象进行加载。
接口数组:
一个Interface对象的数组表示将要给我需要代理的对象提供一组什么接口如果我提供了一组接口给它那么这个代理对象就宣称实现了该接口(多态)这样我就能调用这组接口中的方法了。
调用处理器
一个InvocationHandler接口表示代理实例的调用处理程序实现的接口。每个代理实例都具有一个关联的调用处理程席。对代理实例调用方法时将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法(传入InvocationHandler接口的子类)。
对象接口
package proxy.dynamicproxy.v3;public interface IAnimal {public void run();public void eat();public void sleep();
}
被代理类Cat
package proxy.dynamicproxy.v3;public class Cat implements IAnimal{Overridepublic void run() {System.out.println(Cat Run invoking!!!);}Overridepublic void eat() {System.out.println(Cat eat invoking!!!);}Overridepublic void sleep() {System.out.println(Cat sleep invoking!!!);}
}被代理类Dog
package proxy.dynamicproxy.v3;public class Dog implements IAnimal{Overridepublic void run() {System.out.println(Dog Run invoking!!!);}Overridepublic void eat() {System.out.println(Dog eat invoking!!!);}Overridepublic void sleep() {System.out.println(Dog sleep invoking!!!);}
}代理类工具类
package proxy.dynamicproxy.v3;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyUtils {public Object object;public ProxyUtils(Object object) {this.object object;}public Object createProxyObj(){// 动态代理 顾名思义 针对接口动态生成代理类处理业务逻辑// 返回动态代理/*ClassLoader loader, 要实现接口的类加载器Class?[] interfaces,接口类InvocationHandler h 处理类* **/ClassLoader loader object.getClass().getClassLoader();
// Class?[] interfaces new Class[]{argObj.getClass()}; // 当是接口Class?[] interfaces object.getClass().getInterfaces(); // 当是类直接获取对应的接口方法InvocationHandler handler new IFactoryInvocationHandler();Object object Proxy.newProxyInstance(loader, interfaces, handler);return object;}public class IFactoryInvocationHandler implements InvocationHandler {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(IFactoryInvocationHandler invoke Before!!!);Object rtn method.invoke(object, args);System.out.println(IFactoryInvocationHandler invoke After!!!);return rtn;}}}测试类
package proxy.dynamicproxy;import proxy.dynamicproxy.v3.Cat;
import proxy.dynamicproxy.v3.IAnimal;
import proxy.dynamicproxy.v3.ProxyUtils;public class Test {org.junit.Testpublic void v3_common_test() {// 实例化代理工具类ProxyUtils proxyUtils new ProxyUtils(new Cat());// 创建代理对象IAnimal animal (IAnimal)proxyUtils.createProxyObj();// 调用被代理类的方法animal.eat();System.out.println();animal.run();System.out.println();animal.sleep();System.out.println();}
}运行结果
IFactoryInvocationHandler invoke Before!!!
Cat eat invoking!!!
IFactoryInvocationHandler invoke After!!!IFactoryInvocationHandler invoke Before!!!
Cat Run invoking!!!
IFactoryInvocationHandler invoke After!!!IFactoryInvocationHandler invoke Before!!!
Cat sleep invoking!!!
IFactoryInvocationHandler invoke After!!!
Process finished with exit code 0
3、动态代理原理
JDK动态代理是一种实现代理模式的方式。它利用Java的反射机制在运行时动态地创建代理对象实现对目标对象的代理。
JDK动态代理的原理如下 定义接口首先需要定义一个接口用于描述目标对象和代理对象的共同行为。 实现InvocationHandler接口创建一个实现InvocationHandler接口的代理处理器类该类负责对目标对象的方法进行代理。 获取代理类通过java.lang.reflect.Proxy的静态方法newProxyInstance()创建代理类该方法需要传入ClassLoader、接口数组和InvocationHandler实例。 调用代理对象通过代理对象调用方法时实际上是调用InvocationHandler的invoke()方法。 在invoke()方法中可以进行一些额外的操作比如在调用目标方法之前进行预处理、在调用目标方法后进行后处理等。
4、总结