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方法。