序言
动态代理,是十分常见的,Spring著名的AOP就是基于动态代理实现的,今天我们来学习一下动态代理叭。
代理
代理可以分为两大类:动态代理和静态代理
区别:静态代理在编译时增强,动态代理在运行时增强
静态代理的CODE
//接口:
interface Teacher{
void teach();
}
//接口的实现:
class GoodTeacher implements Teacher{
@Override
public void teach() {
System.out.println("老师教书");
}
}
//代理类
class TeacherProxy implements Teacher{
private Teacher teacher;
TeacherProxy(Teacher teacher){
this.teacher=teacher;
}
@Override
public void teach() {
System.out.println("静态代理开始");
teacher.teach();
System.out.println("代理结束");
}
}
动态代理
动态代理也可以分为两种:JDK动态代理和CgLib动态代理
区别:
- JDK动态代理依赖于接口,被代理的类必须实现接口
- CgLib动态代理不依赖于接口
- JDK在创建对象速度快,运行时速度慢,CgLib创建对象速度慢,运行速度快
JDK动态代理
class ProxyTeacher2{
private GoodTeacher goodTeacher=null;
ProxyTeacher2(GoodTeacher goodTeacher){
this.goodTeacher=goodTeacher;
}
//生成goodTeacher的代理对象
public Teacher getProxy(){
return (Teacher) Proxy.newProxyInstance(goodTeacher.getClass().getClassLoader(), goodTeacher.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(goodTeacher,args);
System.out.println("动态代理增强方法体");
return invoke;
}
});
}
}
CgLib动态代理
class Ogn{
public void buy(int money){
System.out.println("真实对象获取到了"+money);
}
}
public class CgLibProxy {
public static void main(String[] args) {
Ogn ogn=new Ogn();
Ogn DL=(Ogn)Enhancer.create(ogn.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().equals("buy")){
int i=(Integer)args[0];
i*=0.8;
Object invoke = method.invoke(ogn, i);
return invoke;
}
return method.invoke(ogn,args);
}
});
DL.buy(1000);
}
}
需要注意的是使用CgLib需要引入Cglib的jar包
结束
动态代理还是很常见的,很多框架中都是用到了动态代理,所以我们有必要了解掌握动态代理模式