标签:cglib动态代理 cli client tcl turn ade call png 载器
public interface Student { void learn(); void playGame(); }
公共接口
public class Hg implements Student { @Override public void learn() { System.out.println("hg爱学习"); } @Override public void playGame() { System.out.println("hg爱玩游戏"); } }
被代理的类
public class HgHandler implements InvocationHandler { private Object obj=null; public Object getProxy(Object obj){ this.obj=obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this); } //proxy是代理对象的参数,这个参数并不能直接转为代理类接口,但可以返回,因此可以连续调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("learn")){ System.out.println("爱学习吗?"); } if(method.getName().equals("playGame")){ System.out.println("还敢打游戏?"); } Object invoke = method.invoke(obj, args); return null; } }
在这里注意:注入被代理对象是必须的,因为invoke方法中需要使用,而getProxy是非必须的,可以推迟到client中newInstance(),而且在方法中并没有使用proxy,那不由得产生疑问,那这个proxy放在这有啥作用呢,了解后发现,他虽然不能直接使用,但是他可以作为返回值返回,因此可以链式调用(即objProxy.learn().playGame();那如果我们利用proxy是代理这一特性在invoke中强转为Student后,不就可以直接使用了吗,看下图
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Student hg=(Student)proxy; hg.playGame(); return null; }
结果发现堆栈溢出,这是什么操作,仔细想想,就是目前proxy还没有确定自己所代理的对象,然后又将他强转为Student,而代理又去找自己的代理,无限找下去,当然会溢出了
<!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
//cglib通过继承父类,并覆盖父类的方法来实现代理父类,所以一个类被final修饰, // 则该类不能被代理,一个方法被final修饰,则该方法不能贝被覆盖 public class Person { public void dance(){ System.out.println("person 爱跳舞"); } public final void drink(){ System.out.println("person 喝水"); } }
MyMethodInterceptor类
public class MyMethodInterceptor implements MethodInterceptor { /** * * @param o cglib生成的代理对象 * @param method 被代理对象方法 * @param objects 方法入参 * @param methodProxy 代理方法 * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("前置检查"); Object o1 = methodProxy.invokeSuper(o, objects); System.out.println("后置检查"); return o1; } }
method在方法中并没有使用,使用了被代理对象的invokeSuper的methodProxy方法,增强
public class TestCglib { public static void main(String[] args) { Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(Person.class); enhancer.setCallback(new MyMethodInterceptor()); Person per = (Person)enhancer.create(); per.dance(); per.drink(); } }
//cglib通过继承父类,并覆盖父类的方法来实现代理父类,所以一个类被final修饰,
// 则该类不能被代理,一个方法被final修饰,则该方法不能贝被覆盖
public class Person {
public void dance(){
System.out.println("person 爱跳舞");
}
public final void drink(){
System.out.println("person 喝水");
}
}
标签:cglib动态代理 cli client tcl turn ade call png 载器
原文地址:https://www.cnblogs.com/ghghg/p/12722617.html