文章目录
1 基于jdk的动态代理
这里的动态代理是为某接口进行代理,有两个对象被代理类
,代理类
被代理类
: 指被代理的某个接口的实现类
代理类
: 指生成的某个类,相当于被代理类
的一个兄弟类,代理类可以干任何想干的事(它也有被代理类的所有方法并且还能通过编码无侵入更改,包括增加方法执行前后日志,添加功能,增强某方法)。
1.1 准备父接口
public interface Human {
void eat();
void dress();
}
1.2 准备实现类(被代理类)
public class Chinese implements Human{
@Override
public void eat() {
System.out.println("吃大米饭");
}
@Override
public void dress() {
System.out.println("穿中山装");
}
}
1.3 代理对象生成方法
public class ProxyTest {
private static <T> T getDynamicProxyObject(T t) throws IllegalAccessException, InvocationTargetException {
return (T) Proxy.newProxyInstance
(t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
System.out.println("执行方法【" + methodName+"】前");
Object invoke = method.invoke(t, args);
System.out.println("执行方法【" + methodName+"】后");
return invoke;
}
});
}
}
1.4 生成代理对象
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
//[被代理的对象],作为入参获取父接口信息
Human act = new Chinese();
//创建[被代理对象]的[代理对象]
Human proxyChinese = getDynamicProxyObject(act);
proxyChinese.dress();
proxyChinese.eat();
System.out.println(proxyChinese instanceof Human);
System.out.println(proxyChinese instanceof Chinese);
}
1.5 控制台输出
执行方法【dress】前
穿中山装
执行方法【dress】后
执行方法【eat】前
吃大米饭
执行方法【eat】后
true
false
从上面的true false可以看出来,生成的代理类
是一个被代理类
父接口的一个实例,跟例子中被代理类
的Chinese
是兄弟关系
2 基于cglib的动态代理
CGLIB(Code Generation Library)是一个开源类库,需要导入第三方jar包:
asm-7.3.1.jar
,cglib-3.3.0.jar
下载链接: jar包下载地址
cglib生成的代理类跟jdk有点不一样,它是生成被代理类
的子类
2.1 准备类(被代理类)
public class Student {
public void read() {
System.out.println("读书");
}
}
2.2 代理对象生成方法
public class CglibTest {
private static <T> T getCglibProxyObject(T t) throws Throwable {
Object o = Enhancer.create(t.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
String methodName = method.getName();
System.out.println("执行方法【" + methodName + "】前");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("执行方法【" + methodName + "】后");
return invoke;
}
});
return (T) o;
}
}
2.3 生成代理对象
public static void main(String[] args) throws Throwable {
Student student = new Student();
Student proxy = getCglibProxyObject(student);
proxy.read();
System.out.println(proxy instanceof Student);
}
2.4 控制台输出
执行方法【read】前
读书
执行方法【read】后
true
从输出看出来,增强了Student
类中read()
方法,通过true
,我们也知道使用cglib产生Student
的代理对象为其子类