代理模式
什么是代理模式
代理模式的定义: 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
这种类型的设计模式属于结构型模式。
优点:
- 职责清晰。
- 高扩展性。
- 智能化。
缺点:
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
组成
-
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
-
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
-
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
实现
第一种:静态代理
步骤1:创建一个接口
public interface IDemo {
public String print();
}
步骤2: 创建一个该接口的实现类
public class Demo implements IDemo {
public Demo(){
}
public String print(){
System.out.println("this is a demo.");
return "end";
}
}
步骤3:创建一个该接口的代理类,并在代理类初始化的时候接管被代理对象
public class StaticProxy implements IDemo {
IDemo target;
public StaticProxy(IDemo target) {
this.target = target;
}
@Override
public String print() {
System.out.println("before print");
String result = target.print();
System.out.println("after print");
return "print " + result;
}
}
步骤4:执行程序,输出结果:
public static void main(String[] args) {
IDemo demo = new StaticProxy(new Demo());
System.out.println(demo.print());
}
动态代理
步骤1、2同静态代理
步骤3: 创建实现InvocationHandler接口的类
public class ProxyInvocationHandler implements InvocationHandler {
Object target;
public ProxyInvocationHandler(Object obj) {
target = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before " + method.getName());
Object result = method.invoke(target, args);
System.out.println("after " + method.getName());
return "invoke " + result;
}
}
步骤4:创建代理类用以获取Demo类的对象
public class DynamicProxy {
public static Object getProxyObject(Class clazz) throws Exception {
ProxyInvocationHandler handler = new ProxyInvocationHandler(new Demo());
Class c = Proxy.getProxyClass(clazz.getClassLoader(), clazz);
Constructor con = c.getConstructor(InvocationHandler.class);
Object o = con.newInstance(handler);
return o;
}
}
步骤5:执行程序,输出结果
public static void main(String[] args) throws Exception {
IDemo dem = (IDemo) getProxyObject(IDemo.class);
System.out.println(dem.print());
}
CGLIB代理
步骤1:Maven引入CGLIB相关依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
步骤2:创建CglibDemo类
public class CglibDemo{
public String print() {
System.out.println("this is a cglib demo.");
return "end";
}
}
步骤3:创建一个类CglibInterceptor并实现MethodInterceptor接口
public class CglibInterceptor implements MethodInterceptor {
Object target;
public CglibInterceptor(Object target) {
this.target = target;
}
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before " + method.getName());
Object result = methodProxy.invoke(target, args);
System.out.println("after " + method.getName());
return "intercept " + result;
}
}
步骤4:创建CGLIB代理类获取被代理后的对象
public class CglibProxy {
private Object target;
public Object getInstance(final Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(new CglibInterceptor(target));
return enhancer.create();
}
}
步骤5:执行程序,输出结果
public static void main(String[] args) {
CglibDemo cglibDemo = (CglibDemo) new CglibProxy().getInstance(new CglibDemo());
System.out.println(cglibDemo.print());
}