代理模式结构图:
介绍
代理是一种模式,提供了对目标对象的间接访问方式,即通过代理访问目标对象。如此便于在目标实现的基础上增加额外的功能操作,前拦截,后拦截等,以满足自身的业务需求,同时代理模式便于扩展目标对象功能的特点也为多人所用。
两种实现方式,1.实现 2.继承
静态代理
代码结构
Proxied
package com.ldq.impl;
import com.ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:被代理类
*/
public class Proxied implements SubjectService {
public void order() {
System.out.println("执行用户下单逻辑......");
}
}
Proxy(基于继承方式实现)
package com.ldq.proxy;
import com.ldq.impl.Proxied;
import com.ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:29
* @Description: 代理类
*/
public class Proxy extends Proxied {
public void order() {
System.out.println("日志收集开始...");
super.order();
System.out.println("日志收集结束...");
}
}
Proxy(基于实现接口方式实现)
package com.ldq.proxy;
import com.ldq.impl.Proxied;
import com.ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:29
* @Description: 代理类
*/
public class Proxy implements SubjectService {
/**
* 代理的对象
*/
private SubjectService subjectService;
public Proxy(SubjectService subjectService){
this.subjectService = subjectService;
}
public void order() {
System.out.println("日志收集开始...");
subjectService.order();
System.out.println("日志收集结束...");
}
}
SubjectService
package com.ldq.subject;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:主题角色
*/
public interface SubjectService {
void order();
}
ClientTest
package com.ldq;
import com.ldq.proxy.Proxy;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:32
* @Description:
*/
public class ClientTest {
public static void main(String[] args) {
//SubjectService subjectService = new Proxy(new Proxied());
//subjectService.order();
Proxy proxy = new Proxy();
proxy.order();
}
}
静态代理的总结
优点:可以做到不对目标对象进行修改的前提下,对目标对象进行功能的扩展和拦截。
缺点:因为代理对象,需要实现与目标对象一样的接口,会导致代理类十分繁多,不易维护,同时一旦接口增加方法,则目标对象和代理类都需要维护。
JDK动态代理
代码结构
Proxied
package ldq.impl;
import ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:被代理类
*/
public class Proxied implements SubjectService {
public void order() {
System.out.println("执行用户下单逻辑......");
}
}
JdkProxy
package ldq.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 11:09
* @Description:
*/
public class JdkProxy implements InvocationHandler {
public Object target;
public JdkProxy(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始日志收集....");
Object result = method.invoke(target, args);
System.out.println("结束日志收集....");
return result;
}
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
}
SubjectService
package ldq.subject;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:主题角色
*/
public interface SubjectService {
void order();
}
ClientTest
package ldq;
import ldq.impl.Proxied;
import ldq.proxy.JdkProxy;
import ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:32
* @Description:
*/
public class ClientTest {
public static void main(String[] args) {
JdkProxy jdkProxy = new JdkProxy(new Proxied());
SubjectService subjectService = jdkProxy.getProxy();
subjectService.order();
}
}
cgLib实现动态代理
代码结构
Proxied
package ldq.impl;
import ldq.subject.SubjectService;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:被代理类
*/
public class Proxied implements SubjectService {
public void order() {
System.out.println("执行用户下单逻辑......");
}
}
CglibProxy
package ldq.proxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 11:21
* @Description:
*/
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(">>>>cglib日志收集开始....");
Object reuslt = methodProxy.invokeSuper(o, objects);
System.out.println(">>>>cglib日志收集结束....");
return reuslt;
}
}
SubjectService
package ldq.subject;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:28
* @Description:主题角色
*/
public interface SubjectService {
void order();
}
ClientTest
package ldq;
import ldq.impl.Proxied;
import ldq.proxy.CglibProxy;
import ldq.subject.SubjectService;
import net.sf.cglib.proxy.Enhancer;
/**
* @Auther: liangdeqiang
* @Date: 2019-5-17 10:32
* @Description:
*/
public class ClientTest {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
//设置代理类的父类
enhancer.setSuperclass(Proxied.class);
//设置回调对象
enhancer.setCallback(cglibProxy);
//创建代理对象
Proxied proxied = (Proxied) enhancer.create();
proxied.order();
}
}
动态代理总结
JDK动态代理:实现方式是实现接口,利用java的反射执行
cgLib动态代理:实现方式是继承,利用ASM(字节码)技术生成子类