java代理、cglib代理

    技术2022-07-11  132

    这里写目录标题

    java静态代理java动态代理cglib代理实现

    java静态代理

    静态代理A类持有B类,同时实现了C接口,A类通过B类实现,前后增加自己的业务处理逻辑,从而实现对B类的代理。代码示例: 接口类C:

    public interface C { public void printWork(); }

    实现类B:

    public class B implements C { public void printWork() { System.out.println("打印工作"); } }

    代理类A:

    public class A implements C { private C c; public A(C c){ this.c =c ; } public void printWork() { System.out.println("******插电启动*******"); c.printWork(); } public static void main(String[] args) { B b = new B(); b.printWork(); System.out.println("=======启动代理=========="); new A(b).printWork(); } }

    输出结果:

    至此,我们已经简单完成了B类的代理类A.

    java动态代理

    动态代理是指在运行时动态生成代理类,而不需要我们每次指定代理对象和手写代理类,通过动态实现代理。

    代理类需要实现InvocationHandler类。

    java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,由jdk提供,它提供了一组静态方法来为接口动态生成代理类及其对象。在我们上面静态代理中,类似A类的存在,根据接口生成新的实现类

    java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。

    开始修改静态代理A类

    创建AProxy类实现InvocationHandler接口invoke方法Proxy创建封装对象 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class AProxy implements InvocationHandler{ private Object target; //传入需要代理的对象,对应B类引入,此处 //用Object封装 public AProxy(Object object){ this.target=object; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // to do something // 注意,此处使用我们传入的target,并非proxy System.out.println("******插电启动*******"); return method.invoke(target, args); } public Object creactProxyObject(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public static void main(String[] args) { B b = new B(); C c = (C) new AProxy(b).creactProxyObject(); c.printWork(); } }

    输出结果:

    cglib代理实现

    通过上述,我们可以到参数getInterfaces()方法,基于接口方式实现的动态代理。cglib通过继承来实现动态代理。

    引入cglib的依赖,pom文件中增加

    <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>

    创建普通类D:

    public class D { public void sayHello(){ System.out.println("hello,i'm ok"); } }

    创建代理CglibProxy代理类:

    import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{ // 根据一个类型产生代理类 public Object CreatProxyedObj(Class<?> clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("======插入前置通知======"); Object object = arg3.invokeSuper(arg0, arg2); System.out.println("======插入后者通知======"); return object; } public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); D dd = (D) proxy.CreatProxyedObj(D.class); dd.sayHello(); }

    输入结果: 至此:完成了cglib基于继承方式实现的代理,在spring中,sping优先使用jdk动态代理,对于没有接口实现的类,采用cglib方式实现代理。

    Processed: 0.020, SQL: 9