代理设计模式:
1.真实对象
2.代理对象
3.抽象对象(抽象功能)
代理设计模式优点:
1.保护真实对象
2.让真实对象职责更明确
3.扩展
静态代理:
由代理对象代理所有真实对象的功能,需要自己编写代理类,每个代理的功能需要单独编写。
真实对象:
package com;
public class President implements Gongneng {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public President(String name) {
this.name = name;
}
public void talk() {
System.out.println("talk");
}
}
代理对象:
package com;
public class StaticProxy implements Gongneng {
private President president = new President("pre");
@Override
public void talk() {
System.out.println("proxy talk");
president.talk();
}
}
抽象接口:
package com;
public interface Gongneng {
public void talk();
}
Test类:
package com;
public class TestDemo {
public static void main(String[] args) {
StaticProxy proxy = new StaticProxy();
proxy.talk();
}
}
静态代理缺点:当代理功能比较多时,代理类中方法需要写很多。
动态代理:
为解决静态代理需要频繁编写代理功能方法的缺点。
分类:JDK、CGLIB
JDK动态代理:
与CGLIB动态代理对比:
1.优点:JDK自带,不需要导入额外jar包
2.缺点:真实对象必须实现接口;采用反射机制,效率比较低
代理类:(相当于处理程序)
package com;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyOb implements InvocationHandler {
private ProxyedMain proxyedMain = new ProxyedMain();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("预约时间");
Object result = method.invoke(proxyedMain, args);
return result;
}
}
真实对象类:
package com;
public class ProxyedMain implements Gongneng {
@Override
public void chifan() {
System.out.println("吃饭");
}
@Override
public void mubiao() {
System.out.println("目标");
}
}
程序会根据接口创建一个对象,之后当调用该对象的方法时会调用invoke方法(即处理程序)。
package com;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
// 三个参数分别代表类加载器,实现接口,处理程序,返回代理对象
Gongneng gongneng = (Gongneng) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Gongneng.class}, new ProxyOb());
gongneng.chifan();
}
}
Proxy.newProxyInstance中第一个参数表示反射时使用的类加载器,第二个参数表示Proxy需要实现什么接口,第三个参数表示通过接口调用方法时,需要调用哪个类的invoke方法
CGLIB动态代理:
优点:基于字节码,生成真实对象的子类,运行效率高于JDK,不需要实现接口
缺点:第三方非JDK功能,需要额外导入jar包
package com;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyOb implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("预约时间");
// invoke调用子类重写方法
// method.invoke(o,objects);
Object invokeSuper = methodProxy.invokeSuper(o, objects);
return invokeSuper;
}
}
package com;
import net.sf.cglib.proxy.Enhancer;
public class Test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ProxyedMain.class);
enhancer.setCallback(new ProxyOb());
ProxyedMain o = (ProxyedMain) enhancer.create();
o.chifan();
}
}