jdk动态代理和cglib动态代理介绍

传统的日志记录方式,需要在每个需要做日志记录的方法中,逐一添加记录日志的方法,这种方式过于繁琐。
一个项目中的方法有很多,不适用于批量方法的日志记录操作;

衍生jdk动态代理和cglib动态代理2种方式对日志操作进行统一管理
(1)jdk动态代理方式
①:Proxy类是Jdk中自带的一个工具类(反射包下,属于反射的功能),它可以帮我们创建代理类或实例
②:方法newProxyInstance()—用于创建代理对象实例
③:Proxy.newProxyInstance()方法中参数介绍:
参数一:目标对象的类加载器
参数二:目标对象实现的所有接口
参数三:InvocationHandler接口(重写invoke方法后)的实例
注意:InvocationHandler 接口的实现类中—>对代理的目标对象内的方法进行增强操作给目标对象方法前面,后面、返回处、异常处添加额外的功能代码–增强
invoke()方法内的参数介绍:
Object proxy:代理对象实例
Method method:代理对象调用的方法的反射–Method对象实例
Object[] args:调用代理方法时传递进来的参数

注意:
jdk动态代理技术使用前提条件: 目标对象必须要有接口.
优点:这种方式已经解决我们前面所有日记需要的问题。非常的灵活。而且可以方便的在后期进行维护和升级。
缺点:当然使用jdk动态代理,必需要有接口。如果没有接口,就无法使用jdk动态代理技术。
示例:明星(目标对象),经纪人(代理对象),方法(强化品牌代言功能) ,由明星操作改为经纪人操作

代码演示:

public static Object createproxy(Object target){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*System.out.println(method);
System.out.println(Arrays.asList(args));*/

Object result = null;
LogUtils.logBefore(method.getName(),args);
try{
//1、执行代理对象的操作
result = method.invoke(target,args);
//2、增强操作---就是日志记录操作
LogUtils.logAfterReturning(method.getName(),result);
}catch (Exception e){
//3、异常处理操作
LogUtils.logAfterThrowing(method.getName(),e);
}
return result;
}
});
}

(2)cglib动态代理方式
①:cglib跟jdk动态代理的不同是:如果目标对象没有实现接口,
cglib同样可以对其进行增强操作(增强就是在目标就去的前面,后面,返回处,异常处添加额外的功能操作)。
②:cglib动态代理,它不是jdk中自带的代理技术
③: Cglib动态代理,是根据目标对象的字节码来进行修改,并产生一个子类。从而达到增强的效果。
④:new MethodInterceptor()接口:作用和invocationHandler接口功能一致
⑤:intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)方法
参数一:cglib产生的代理对象实例
参数二:调用的方法的反射对象实例
参数三:调用方法时,传递参数
参数四:调用的方法反射对象实例的代理对象
返回值:返回值就是调用代理方法时的返回值
注意:在该方法中增强部分,有关异常的出路需要throw e,对异常进行处理
⑥:创建Cglib代理对象实例—>enhancer.create();

Cglib动态代理的优点:Cglib动态代理要比Jdk动态代理要强,因为它可以在没有接口的情况下。也可以对对象进行增强操作。
缺点:不管是Jdk动态代理,还是Cglib动态代理。都需要我们自己编码去实现这些增强操作。

代码演示:

public static Object createCglibProxy(Object target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());

enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
try {
//前置通知
LogUtils.logBefore(method.getName(), args);
Object result = method.invoke(target, args);
//返回通知
LogUtils.logAfterReturning(method.getName(), result);
return result;
} catch (Exception e) {
//异常通知
LogUtils.logAfterThrowing(method.getName(), e);
throw e;
}
}
});
return enhancer.create();
}