java 动态代理

1.定义java实体类

import lombok.Data;

@Data
public class Role {
    private int id;
    private String name;

    public Role(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

2.RoleService接口

import com.imooc.myo2o.entity.Role;

public interface RoleService {
    public void printRole(Role role);
}

3.RoleServiceImpl实现RoleService接口

import com.imooc.myo2o.entity.Role;
import com.imooc.myo2o.service.RoleService;

public class RoleServiceImpl implements RoleService {

    @Override
    public void printRole(Role role) {
        System.out.println(role.toString());
    }
}

4.定义拦截器

public interface Interceptor {
    public void before(Object object);

    public void after(Object object);

    public  void afterReturn(Object object);

    public  void afterThrow(Object object);
}

5.实现拦截器

public class RoleInterceptor implements Interceptor {
    @Override
    public void before(Object object) {
        System.out.println("准备打印角色信息");
    }

    @Override
    public void after(Object object) {
        System.out.println("完成打印角色信息");
    }

    @Override
    public void afterReturn(Object object) {
        System.out.println("完成打印,一切正常");
    }

    @Override
    public void afterThorw(Object object) {
        System.out.println("异常了,看一下啊角色是否为空");
    }
}

6.ProxyBeanUtil

import com.imooc.myo2o.Interceptor.Interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyBeanUtil implements InvocationHandler {
    // 被代理对象
    private Object obj;
    // 拦截器
    private Interceptor interceptor;

    /**
     * @param obj         被代理对象
     * @param interceptor 拦截器
     * @return 动态代理对象
     */
    public static Object getBean(Object obj, Interceptor interceptor) {
        ProxyBeanUtil proxyBeanUtil = new ProxyBeanUtil();
        proxyBeanUtil.obj = obj;
        proxyBeanUtil.interceptor = interceptor;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), proxyBeanUtil);

    }

    /**
     * @param proxy  代理对象
     * @param method 当前调度的方法
     * @param args   参数
     * @return 方法返回
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnObj = null;
        boolean flag = false;
        interceptor.before(obj);
        try {
            returnObj = method.invoke(obj, args);
        } catch (Exception e) {
            flag = true;
        } finally {
            interceptor.after(obj);
        }
          if (!flag) 
            interceptor.afterReturn(obj);
        } else {
            interceptor.afterThorw(obj);
        }
        return returnObj;
    }
}

7.测试

public class RoleTest {
    public static void main(String[] args) {
        RoleService roleService = new RoleServiceImpl();
        Interceptor interceptor = new RoleInterceptor();
        RoleService proxy = (RoleService) ProxyBeanUtil.getBean(roleService, interceptor);
        Role role = new Role(1, "张三");
        proxy.printRole(role);
        role = null;
        proxy.printRole(role);
    }
}

8.结果

准备打印角色信息
Role{id=1, name=‘张三’}
已经完成打印角色信息
完成打印,一切正常

准备打印角色信息
已经完成打印角色信息
异常了,看一下啊角色是否为空

9.分析

核心代码为
// 生成代理对象,绑定代理方法
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), proxyBeanUtil);
当调用printRole方法时,会进入当前的invoke方法中,此时,
1.调用拦截器的before方法,打印出“准备打印角色信息”,
2.开始反射原有的方法,打印“Role{id=1, name=‘张三’}”
3.调用after方法,打印“已经完成打印角色信息”
4.把对象置为null
5.在执行一遍printRole方法,此时role为空。
6.先执行before方法,然后执行after方法,最后执行afterThrow方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值