一、什么是代理模式?有和作用?
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。然后通过控制被代理类对方法的访问来很好的对外隐藏这个这个被代理类的具体信息。为其他对象提供一种代理以控制对这个对象的访问。说白了:就是通过访问被代理类来达到在直接访问被代理类的前后做一些扩展功能的操作。
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
一、静态代理的实现
1、ISource接口,代理类与被代理类共同实现。
public interface ISource {
public void method();
}
2、被代理类
public class Sourceable implements ISource {
@Override
public void method() {
System.out.println("我是被代理类!");
}
}
3、代理类:持有被代理类的对象实例。
public class Proxy implements ISource {
private Sourceable source;
public Proxy() {
this.source = new Sourceable();
}
@Override
public void method() {
before();
source.method();
after();
}
private void before(){
System.out.println("aa");
}
private void after(){
System.out.println("bb");
}
}
4、测试类
public class ProxyTest {
public static void main(String[] args) {
//通过接口,实例化代理类,
ISource source = new Proxy();
//调用代理类的方法
source.method();
}
}
二、JDK动态代理
1、1,2步骤同上;
2、代理类
public class SourceProxy implements InvocationHandler{
//目标对象
private Object target;
public SourceProxy(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("aa");
Object rs = method.invoke(target,args);
System.out.println("bb");
return rs;
}
}
3、测试类
public static void main(String[] args) {
ISource source = new Source();
SourceProxy myInvocationHandler = new SourceProxy(source);
//代理对象
ISource proxySource = (ISource) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{ISource.class}, myInvocationHandler);
proxySource.method();
}
三、Cglib动态代理(需要包cglib-2.2.3.jar;cglib-nodep-2.2.2.jar;asm.jar)
1、被代理类Source
public class Source {
// 可以被代理
public void eat() {
System.out.println("我是被代理类aa");
}
// final 方法不会被生成的字类覆盖
public final void work() {
System.out.println("我是被代理类bb");
}
// private 方法不会被生成的字类覆盖
private void play() {
System.out.println("我是被代理类cc");
}
}
2、代理类
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("aa");
Object result = method.invoke(target, objects);
System.out.println("bb");
return result;
}
public static Object getProxy(Object target) {
Enhancer enhancer = new Enhancer();
// 设置需要代理的对象
enhancer.setSuperclass(target.getClass());
// 设置代理人
enhancer.setCallback(new CglibProxy(target));
return enhancer.create();
}
}
3、测试类
public class Test {
public static void main(String[] args) {
// 生成 Cglib 代理类
Source engineerProxy = (Source) CglibProxy.getProxy(new Source());
// 调用相关方法
engineerProxy.eat();
}
}