java动态代理和cglib动态代理java 动态代理
动态代理应用广泛,Spring,Struts等框架很多功能是通过动态代理,或者进一步封装来实现的。
常见的动态代理模式实现有Java API提供的动态代理和第三方开源类库CGLIB动态代理。
Java API提供的动态代理是基于类反射实现的,用到的类有:
java.lang.reflect.InvocationHandler;
java.lang.reflect.Method;
java.lang.reflect.Proxy;
其实现是通过Proxy类的newProxyInstance()方法产生代理对象。自定义动态代理类需要实现InvocationHandler接口,该接口只有一个invoke()方法。
CGLIB是通过生成java 字节码从而动态的产生代理对象,因此需要字节码解析处理的依赖asm类库,字节码动态生成的代理对象实际上是继承了真实主题类的。这种实现方式需要导入cglib和asm的类库。下面用到的例子是cglib-2.2.2.jar, asm-3.3.1.jar。cglib使用了MethodInterceptor,其中的方法是intercept(),这是拦截的概念,很容易就想到了Struts2的拦截器。
比较之下,Java API提供的动态代理需要面向接口,产生代理对象,因此真实主题实现类必须实现了接口才可以。而CGLIB不需要面向接口,可以代理简单类,但由于动态代理对象是继承真实主题实现类的,因此要求真实主题实现类不能是final的。
下面是实现的例子。
首先,为了看到动态代理可以根据不同类动态产生不同代理的效果,我们新建两个接口,及其实现类。
package leon.aj.dynproxy.target; public interface Hello { public String sayHello(String name); }实现类:
package leon.aj.dynproxy.target; public class HelloImpl implements Hello { @Override public String sayHello(String name) { String s = "Hello, "+name; System.out.println(this.getClass().getName()+"->"+s); return s; } }另一接口和实现类:
package leon.aj.dynproxy.target; public interface UserDao { public boolean login(String username,String password); } package leon.aj.dynproxy.target; public class UserDaoImpl implements UserDao { @Override public boolean login(String username, String password) { String user = "("+username+","+password+")"; System.out.println(this.getClass().getName()+"-> processing login:"+user); return true; } }
应用Java API实现的动态代理类:
测试:
package leon.aj.dynproxy.java; import leon.aj.dynproxy.target.Hello; import leon.aj.dynproxy.target.HelloImpl; import leon.aj.dynproxy.target.UserDao; import leon.aj.dynproxy.target.UserDaoImpl; public class TestJavaProxy { public static void main(String[] args) { JavaDynProxy proxy = new JavaDynProxy(); Hello hello = (Hello)proxy.getProxyInstance(new HelloImpl()); String s = hello.sayHello("Leon"); System.out.println(s); UserDao userDao = (UserDao) proxy.getProxyInstance(new UserDaoImpl()); userDao.login("Leon", "1234"); System.out.println(userDao.getClass().getName()); } }
下面是采用cglib实现的例子:
测试类:
package leon.aj.dynproxy.cglib; import leon.aj.dynproxy.target.Hello; import leon.aj.dynproxy.target.HelloImpl; import leon.aj.dynproxy.target.UserDaoImpl; public class TestCiglib { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Hello hello = (Hello) proxy.getProxyInstance(new HelloImpl()); System.out.println(hello.sayHello("Leon")); UserDaoImpl userDao = (UserDaoImpl) proxy.getProxyInstance(new UserDaoImpl()); userDao.login("Leon", "1234"); System.out.println(userDao.getClass().getSuperclass());//看动态代理实例的父类 } }谁与争锋,JDK动态代理大战CGLib动态代理jdk动态代理和cglib动态代理
代理模式之静态代理,JDK动态代理和cglib动态代理jdk cglib动态代理
java中的静态代理、jdk动态代理和cglib动态代理jdk cglib动态代理
代理模式-动态代理详解(JDK动态代理和CGLIB动态代理)jdk cglib动态代理
AOP实现--JDK中的动态代理和cglib代理jdk和cglib动态代理区别
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理jdk静态代理和动态代理
Java JDK中的静态代理、动态代理&Cglib动态代理jdk cglib动态代理
jdk动态代理和cglib动态代理cglib代理和jdk动态代理区别
JDK动态代理和CGLib动态代理的对比cglib代理和jdk动态代理区别