定义接口:
public interface Persion {
//找对象
public void findLove();
//吃午饭
public void eat();
}
接口实现类(被代理的对象):
public class ZhangSan implements Persion {
@Override
public void findLove() {
System.out.println("zhangsan找对象");
}
@Override
public void eat() {
System.out.println("zhangsan在吃东西");
}
}
public class LiSi implements Persion {
@Override
public void findLove() {
System.out.println("lisi找对象");
}
@Override
public void eat() {
System.out.println("lisi在吃东西");
}
}
1:首先示例静态代理的写法:
代理类:
public class LifeHelp implements Persion{
//需要被代理的对象
private Persion persion;
public LifeHelp(Persion persion) {
this.persion = persion;
}
@Override
public void findLove() {
System.out.println("联系婚姻中介");
persion.findLove();
System.out.println("是否继续");
}
@Override
public void eat() {
System.out.println("外卖员取外卖");
persion.findLove();
System.out.println("吃完休息会");
}
}
测试类:
public class StaticTest {
public static void main(String[] args) {
LifeHelp zhangsan = new LifeHelp(new ZhangSan());
zhangsan.findLove();
System.out.println("====================");
LifeHelp lisi = new LifeHelp(new LiSi());
lisi.eat();
}
}
缺点:代理类扩展较为繁琐,引入动态代理
2:jdk 动态代理
代理类:
public class LifeHelp implements InvocationHandler {
//需要被代理的对象
private Persion targt;
public LifeHelp(Persion targt) {
this.targt = targt;
}
//返回生成的代理对象(字节码重组)
//1:代理对象存在于内存中 2:与被代理对象实现同样的接口
public Persion getInstance(){
Class<? extends Persion> aClass = targt.getClass();
Object o = Proxy.newProxyInstance(aClass.getClassLoader(), aClass.getInterfaces(), this);
return (Persion) o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("找人帮忙开始");
method.invoke(targt,args);
System.out.println("找人帮忙结束");
return null;
}
}
测试类:
public class JDKTest {
public static void main(String[] args) {
LifeHelp zhangsan = new LifeHelp(new ZhangSan());
System.out.println(zhangsan.getInstance().getClass());
zhangsan.getInstance().eat();
//将代理类下载到本地,查看其结构
byte[] bytes = ProxyGenerator.generateProxyClass("LifeHelp", new Class[]{Persion.class});
try {
FileOutputStream fos=new FileOutputStream("D://LifeHelp.class");
fos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("====================");
LifeHelp lisi = new LifeHelp(new LiSi());
System.out.println(lisi.getInstance().getClass());
}
}
备注:基于JDK 方式实现的动态代理,要求被代理类必须实现接口,然后在程序运行时通过反射获取信息,生成代理类,加载到JVM内存中
这个代理类,我们可以下到本地,看它的代码结构
public final class LifeHelp extends Proxy implements Persion {
private static Method m1;
private static Method m3;
private static Method m4;
private static Method m2;
private static Method m0;
public LifeHelp(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void eat() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void findLove() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.qingnian.dynamicproxy.jdk.Persion").getMethod("eat");
m4 = Class.forName("com.qingnian.dynamicproxy.jdk.Persion").getMethod("findLove");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
3:cglib 方式的代理类
public class WangWu {
public void findLove() {
System.out.println("wangwu找对象");
}
public void eat() {
System.out.println("wangwu在吃东西");
}
}
public class LifeHelp implements MethodInterceptor {
//被代理的对象
private Object target;
public Object getInstance(Object source){
target=source;
Enhancer enhancer=new Enhancer();
//设置需要代理的类(生成的代理类会继承这个被代理的类)
enhancer.setSuperclass(source.getClass());
//设置由被代理类的那个子类去执行代理类方法
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//业务增强
System.out.println("找人帮忙开始");
//调用被代理类的方法
methodProxy.invokeSuper(o,objects);
System.out.println("找人帮忙结束");
return null;
}
}
public class CglibTest {
public static void main(String[] args) {
LifeHelp help = new LifeHelp();
Object instance = help.getInstance(new WangWu());
System.out.println(help.getInstance(new WangWu()));
}
}