AOP proxy的优缺点分别是什么?如何使用?

XIAO 2020-04-18 12:48:37 java常见问答 9003

就拿在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一些知识问答记得关注本站消息哦。