一、定义
二、适用场景
三、优缺点
1、优点
2、缺点
四、代码实现
1、静态代理
2、动态代理
2.1、JDK
public class OrderServiceDynamicProxy implements InvocationHandler {
private Object target;
public OrderServiceDynamicProxy(Object target) {
this.target = target;
}
public Object bind(){
Class cls = target.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object argObject = args[0];
beforeMethod(argObject);
Object object = method.invoke(target,args);
afterMethod();
return object;
}
private void beforeMethod(Object obj){
int userId = 0;
System.out.println("动态代理 before code");
if(obj instanceof Order){
Order order = (Order)obj;
userId = order.getUserId();
}
int dbRouter = userId % 2;
System.out.println("动态代理分配到【db"+dbRouter+"】处理数据");
//todo 设置dataSource;
DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter));
}
private void afterMethod(){
System.out.println("动态代理 after code");
}
}
2.2、Cglib
:::warning
基于继承
:::
public class CglibProxy implements MethodInterceptor {
/**
* 被代理对象
*/
private Object target;
/**
* 利用构造函数设置被代理对象
*
* @param target
*/
public CglibProxy(Object target) {
this.target = target;
}
/**
* 创建代理对象
*
* @return
*/
public Object newProxyInstance() {
/**
* 创建Enhancer实例
*/
Enhancer enhancer = new Enhancer();
/**
* 设置被代理类
*/
enhancer.setSuperclass(this.target.getClass());
/**
* 设置回调
*/
enhancer.setCallback(this);
/**
* 创建代理
*/
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(o, objects);
after();
return new Dog();
}
private void before(){
System.out.println("Cglib动态代理-方法前调用");
}
private void after(){
System.out.println("Cglib动态代理-方法后调用");
}
}
2.3、两种动态代理性能比较
2.4、Spring代理的选择
- 当Bean有实现接口时,Spring就会用JDK的动态代理
- 当Bean没有实现接口时,Spring适用Cglib
- 可以强制使用Cglib
- 在spring配置中加入
<aop:aspectj-autoproxy proxy-target-class="true"/>
- 在spring配置中加入