就拿在java软件开发行业比较流行主流框架Spring来说吧,其中AOP proxy就是不可或缺的一部分,对java开发框架感兴趣的朋友们,你们清楚AOP proxy的优缺点吗?一般怎么使用它呢?
所谓AOP proxy即AOP代理,AOP代理又分为动态代理和静态代理,其中动态代理又分为JDK动态代理和CGLib动态代理。
JDK提供了动态代理的方式,可以生成代理类,被代理类和接口沿用静态代理中的IUserDao和UserDao,UserDao为被代理类,下面看代理类,
/* *<p>Title: DynamicProxy</p> * <p>Description: 动态代理类</p> * <p>Company: </p> * @author Administrator * */ public class DynamicProxy implements InvocationHandler { //被代理类的实例 private IUserDao iud = null; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = null; System.out.println("开始JDK动态代理"); method.invoke(iud, args); System.out.println("结束JDK动态代理"); return result; } //构造方法 public DynamicProxy(IUserDao iud) { this.iud = iud; } }
需要实现JDK中的InvocationHandler接口,实现其中的invoke方法,在此方法中通过反射的方式调用被代理类的方法,可以在方法执行前或后进行别的处理,下面看测试代码:
public class Test2 { public static void main(String[] args) { // TODO Auto-generated method stub UserDao ud = new UserDao(); DynamicProxy dp = new DynamicProxy(ud); //生成代理对象 IUserDao iud = (IUserDao) Proxy.newProxyInstance(ud.getClass() .getClassLoader(), ud.getClass() .getInterfaces(), dp); iud.save(); System.out.println("--------------"); iud.find(); } }
在测试代码中通过Proxy类的newProxyInstance方法,生成代理类的实例iud,需要三个参数,第一个为被代理类的类加载器,第二个为被代理类实现的接口,第三个则为invocationHandler的实现类,这样就生成了代理对象。
JDK的动态代理也存在不足,即被代理类必须要有实现的接口,如没有接口则无法使用JDK动态代理(从newProxyInstance方法的第二个参数可得知,必须传入被代理类的实现接口),那么需要使用CGLib动态代理。
CGLib动态代理是一个第三方实现的动态代理类库,不要求被代理类必须实现接口,它采用的是继承被代理类,使用其子类的方式,弥补了被代理类没有接口的不足,要使用CGLib代理需要实现其MethodInterceptor接口,
public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // TODO Auto-generated method stub System.out.println("开始CGLib动态代理"); Object object = proxy.invokeSuper(obj, args); System.out.println("结束CGLib动态代理"); return object; } }
其,测试代码如下,
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserDao.class); enhancer.setCallback(new MyMethodInterceptor()); //生成代理类 UserDao ud = (UserDao) enhancer.create(); ud.save(); System.out.println("----------------"); ud.find(); } }
可以看出使用Enhancer生成代理类,需要设置被代理类,也就是父类(从这里可以看出是使用继承,生成的子类),设置回调方法。在设置回调enhancer.setCallback的时候需要传入MethodInterceptor的实例,这里可以使用匿名内部类的方式,可参照上面的。
静态代理的维护成本比较高,有一个被代理类就需要创建一个代理类,而且需要实现相同的接口。JDK动态代理模式和CGLib动态代理的区别是JDK动态代理需要被代理类实现接口,而CGLib则是生成被代理类的子类,要求被代理类不能是final的,因为final类无法被继承。
那么以上就是有关AOP proxy的优缺点的所有内容了,还想了解更多java一些知识问答记得关注本站消息哦。