JDK动态代理与CGLIB代理

AOP 即面向切面编程。通常用来处理具有横切性质的系统级别服务,比如事务,安全,缓存等。


AOP 代理主要分为两大类:

静态代理:使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;静态代理以 AspectJ 为代表。

动态代理:在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。Spring AOP 用的就是 动态代理。


AspectJ静态代理就不介绍了。


下面介绍动态代理的两种方式。

第一种:JDK动态代理

代码如下

接口

package com.cbf4life;

/**
 * Created by Maggie on 2017/6/7.
 */
public interface Bean {
    void print();
}
实现累

package com.cbf4life.common;

import com.cbf4life.Bean;

/**
 * Created by Maggie on 2017/6/7.
 */
public class TargetBean implements Bean{
    private String name;

    public TargetBean(){}

    public TargetBean(String name){this.name = name;}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void print(){
        System.out.println("hello world");
    }
}

代理工厂

package com.cbf4life;

import com.cbf4life.common.TargetBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by Maggie on 2017/6/7.
 */
public class ProxyFactory implements InvocationHandler {

    private Object bean;
    public Object createBeanProxy(Object be){
        this.bean = be;
        return Proxy.newProxyInstance(be.getClass().getClassLoader(),
                be.getClass().getInterfaces(), this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        TargetBean s = (TargetBean)bean;
        Object object = null;
        if(s.getName() != null)
            object = method.invoke(bean, args);
        else
            System.out.println("名字为空,代理类已经拦截!");
        return object;
    }
}

这就是JDK动态代理,下面是解释

  • 目标对象必须实现接口。
  • 调用Proxy.newProxyInstance()方法,返回创建的代理对象。
  • 由于该方法需要一个实现了InvocationHandler接口的对象,所以我们还要重写该接口的invoke()方法。
  • 我们的限制条件就可以放在这个invoke()方法中,当满足条件,就调用method.invoke()真正的调用目标对象的方法,否则,不做任何事情,直接过滤。

第二种:CGLIB动态代理

需要jar包:

代码实例

package com.cbf4life;

import com.cbf4life.common.TargetBean;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.annotation.Target;
import java.lang.reflect.Method;

/**
 * Created by Maggie on 2017/6/7.
 */
public class CGlibProxyFactory implements MethodInterceptor {

    private Object object;
    public Object createTargetBean(Object object){
        this.object = object;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    public Object getObject() {
        return object;
    }
    public void setObject(Object object) {
        this.object = object;
    }
    @Override
    public Object intercept(Object proxy, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        TargetBean stu = (TargetBean)object;
        Object result = null;
        if(stu.getName() != null)
            result = methodProxy.invoke(object, args);
        else
            System.out.println("方法已经被拦截...");
        return result;
    }


}

总体来说,使用CGlib的方法和使用Proxy的方法差不多,只是Proxy创建出来的代理对象和目标对象都实现了同一个接口。而CGlib的方法则是直接继承了目标对象。


下面是main方法的测试

public static void main(String[] args) {
    Bean stu1 = (Bean)(new ProxyFactory().createBeanProxy(new TargetBean()));
    Bean stu2 = (Bean)(new ProxyFactory().createBeanProxy(new TargetBean("aaa")));
    TargetBean stu3 = (TargetBean)(new CGlibProxyFactory().createTargetBean(new TargetBean()));
    TargetBean stu4 = (TargetBean)(new CGlibProxyFactory().createTargetBean(new TargetBean("aaa")));
    stu1.print();
    stu2.print();
    stu3.print();
    stu4.print();
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值