title: spring05
date: 2020-03-09 19:31:42
tags:代理模式
该部分学习了动态代理。
1、概述
**该部分摘抄自秦老师的博客 **
-
静态代理
- 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
- 公共的业务由代理来完成 . 实现了业务的分工 。
- 公共业务发生扩展时变得更加集中和方便 .
缺点 :
- 类多了 , 多了代理类 , 工作量变大了 . 开发效率降低 .
-
动态代理
- 动态代理的角色和静态代理的一样 .
- 动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
- 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
- 基于接口的动态代理----JDK动态代理
- 基于类的动态代理--cglib
- 现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist
- 我们这里使用JDK的原生代码来实现,其余的道理都是一样的!
2、环境
-
接口
package com.nevesettle.dongtai; public interface Userdao { public void addUser(); public void deleteUser(); public void queryUser(); public void updateUser(); }
-
实现类
package com.nevesettle.dongtai; public class UserdaoImp implements Userdao { public void addUser() { System.out.println("add"); } public void deleteUser() { System.out.println("delete"); } public void queryUser() { System.out.println("query"); } public void updateUser() { System.out.println("update"); } }
假设现在有了新的需求,需要在该接口的各个方法执行之前加一个日志输出,本着不修改原代码的理念,我们可以使用代理模式来满足该需求(Spring的AOP也算基于代理模式来实现的)。
3、代理类
这是一个基本的模板。
package com.nevesettle.dongtai;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return null;
}
private void log(String msg){
System.out.println("执行了"+ msg + "方法");
}
}
- 其中getProxy方法是生成一个动态的代理
- 方法中的第一个参数传的是类加载器,格式是固定的
- 第二个参数传的是需实现类所继承的接口。
- invoke便是要执行的方法了
- 参数method是代理要执行的方法
在invoke中可以进行改造了,在要执行的方法之前加入我们新增的需求即可。