一.静态代理和动态代理
简单来说代理就像是中介,传递给客户端看的代码 (代理代码可以加一些自己的记录日志和事务,就不用在源代码上修改了)
1.1静态代理详解:
1.2动态代理详解:
二.代码举例:
PayService接口:
package net.xdclass.sp.proxy;
public interface PayService {
/**
* 支付回调
* @param outTradeNo
* @return
*/
String callback(String outTradeNo);
/**
* 下单
* @param userId
* @param productId
* @return
*/
int save(int userId,int productId);
}
PayServiceImpl(接口类重写)
package net.xdclass.sp.proxy;
public class PayServiceImpl implements PayService {
public String callback(String outTradeNo) {
System.out.println("目标类 PayServiceImpl 回调 方法 callback");
return outTradeNo;
}
public int save(int userId, int productId) {
System.out.println("目标类 PayServiceImpl 回调 方法 save");
return productId;
}
}
2.1 StaticProxServiceImpl(静态代理类)
整体结构和目标类是一样的
然后就可以加自己想加的东西,其中注入payservice这个类用的是构造函数注入
package net.xdclass.sp.proxy;
public class StaticProxyPayServiceImpl implements PayService {
private PayService payService;
public StaticProxyPayServiceImpl(PayService payService){
this.payService = payService;
}
public String callback(String outTradeNo) {
System.out.println("StaticProxyPayServiceImpl callback begin");
String result = payService.callback(outTradeNo);
System.out.println("StaticProxyPayServiceImpl callback end");
return result;
}
public int save(int userId, int productId) {
System.out.println("StaticProxyPayServiceImpl save begin");
int id = payService.save(userId, productId);
System.out.println("StaticProxyPayServiceImpl save end");
return id;
}
}
测试结果:
区分线区分线区分线区分线区分线区分线区分线区分线
2.2 动态代理:jdkProxy
反射知识
package net.xdclass.sp.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy implements InvocationHandler {
//目标类
private Object targetObject;
//获取代理对象
public Object newProxyInstance(Object targetObject){
this. targetObject = targetObject;
//绑定关系,也就是和具体的哪个实现类关联
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) {
Object result = null;
try{
System.out.println("通过JDK动态代理调用 "+method.getName() +", 打印日志 begin");
result = method.invoke(targetObject,args);
System.out.println("通过JDK动态代理调用 "+method.getName() +", 打印日志 end");
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
测试结果:
2.3 CGLib动态代理
package net.xdclass.sp.proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
//目标类
private Object targetObject;
//绑定关系
public Object newProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
//设置代理类的父类(目标类)
enhancer.setSuperclass(this.targetObject.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建子类(代理对象)
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result = null;
try{
System.out.println("通过CGLIB动态代理调用 "+method.getName() +", 打印日志 begin");
result = methodProxy.invokeSuper(o,args);
System.out.println("通过CGLIB动态代理调用 "+method.getName() +", 打印日志 begin");
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
测试结果: