JAVA JDK动态代理和CGLIB动态代理
来源:互联网 发布:美国经济数据日历 编辑:程序博客网 时间:2024/06/06 10:55
静态代理比较简单和装饰模式很相似,网上一堆资料,下面说说动态代理.
JDK的动态代理是基于接口的,需要代理类和目标类都实现同一个接口,
cglib的动态代理是基于类继承的,针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 ,所以被代理的类不能声明为final类型.
并且使用JDK代理去动态读取某个目标类上面的自定义注解的属性你会发现读取不到,并且元注解使用的是RetentionPolicy.RUNTIME属性,但是不通过动态代理直接获取却能获取到,这是因为JDK的动态代理是基于接口的,所以用jdk动态代理通过method的 isAnnotationPresent(Annotation.class)方法读取目标类的方法注解就读取不到了,可以将目标类上面的注解放到接口上面去,然后使用JDK动态代理就能获取到了,当然如果使用CGLIB的动态代理就不存在这个问题了.
下面用代码来简单测试下jdk和cglib的动态代理,在目标类的show方法上面加上自定义注解,并且使用动态代理在方法前后进行面向切面编程.
项目结构如下:
先写一个自定义注解MyAnnotation:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation { String value();}
代理接口类:
public interface MyService { void show(String name);}
代理目标类:
public class MyServiceImpl implements MyService { @MyAnnotation(value = "myAnnotation") public void show(String name) { System.out.println("show name is " + name); }}
jdk的动态代理类:
public class JAVAAPIProxy implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JAVAAPIProxy before"); method.invoke(target, args); System.out.println("JAVAAPIProxy after"); boolean b = method.isAnnotationPresent(MyAnnotation.class); System.out.println("JAVAAPIProxy " + b); return null; }}
cglib的动态代理类:
public class CGLIBProxy implements MethodInterceptor { private Object target; public Object bind(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("CGLIBProxy before"); method.invoke(target, objects); System.out.println("CGLIBProxy after"); boolean b = method.isAnnotationPresent(MyAnnotation.class); System.out.println("CGLIBProxy "+b); return null; }}
测试主函数类:
public class MainClass { public static void main(String[] args) { testJAVAAPIProxy(); testCGLIBProxy(); } public static void testJAVAAPIProxy() { MyServiceImpl s = new MyServiceImpl(); JAVAAPIProxy proxy = new JAVAAPIProxy(); MyService bind = (MyService) proxy.bind(s); bind.show("lijie"); } public static void testCGLIBProxy() { MyServiceImpl s = new MyServiceImpl(); CGLIBProxy proxy = new CGLIBProxy(); MyServiceImpl bind = (MyServiceImpl) proxy.bind(s); bind.show("lijie"); }}
测试结果:
阅读全文
1 0
- Java静态代理和jdk动态代理、Cglib动态代理
- java动态代理 JDK、Cglib动态代理
- JDK动态代理和CGLIB动态代理
- JDK动态代理和CGLIB动态代理
- JDK动态代理和Cglib动态代理
- Cglib动态代理和jdk动态代理
- jdk动态代理和CGlib动态代理
- jdk动态代理和cglib动态代理
- Java动态代理(jdk代理和cglib代理)
- Java JDK动态代理和cglib动态代理
- JAVA JDK动态代理和CGLIB动态代理
- 大话java之JDK动态代理和CGLIB动态代理
- java的jdk动态代理和cglib动态代理区别
- java动态代理(JDK和cglib)
- java动态代理(JDK和cglib)
- java动态代理(JDK和cglib)
- java动态代理(JDK和cglib)
- java动态代理(JDK和cglib)
- 冒泡排序--java
- Java实现计算当前月天数
- Java_15 集合类接口的常用方法
- window.onload 和$(document).ready的区别
- shell中的重定向 1>&2 2>&1 >&2
- JAVA JDK动态代理和CGLIB动态代理
- 2017多校训练八-1011(hdu 6143 Killer Names)
- qt基础3
- JavaScript知识点之执行上下文
- Codeforces 545D
- Liunx环境启动tomact与查看日志
- spring源码解析-AOP原理
- 指定代码放哪个cpu运行
- Sequence