为什么要学习代理模式?因为这就是SpringAOP的底层! [SpringAOP 和SpringMVC]
代理模式的分类:
1.静态代理
2.动态代理
静态代理
角色分析:
1.抽象角色: 一般会使用接口或者抽象类来解决
2.真实角色:被代理的角色
3.代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
4.客户:访问代理对象的人!
代理模式的好处:
1.可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
2.公共也就就交给代理角色!实现了业务的分工!
3.公共业务发生扩展的时候,方便集中管理!
缺点:
1.一个真实角色就会产生一个代理角色;代码量会翻倍~开发效率会变低~
不改变原来的代码,生成额外的业务
动态代理
1.动态代理和静态代理角色一样
2.动态代理的代理类是动态生成的,不是我们直接写好的!
3.动态代理分为两大类:基于接口的动态代理,基于类的动态代理
(1)基于接口:JDK动态代理
(2)基于类:cglib
(3)java字节码实现 :javasist
需要了解两个类: Proxy: 代理,InvocationHandler: 调用处理程序
动态代理的好处:
1.可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
2.公共也就就交给代理角色!实现了业务的分工!
3.公共业务发生扩展的时候,方便集中管理!
4.一个动态代理类代理的是一个接口,一般就是对应的一类业务
5.一个动态代理类可以代理多个类,只要是实现了同一个接口即可
如何实现动态代理:
1、编写InvocationHandler动态代理类
(1)设置被代理的接口(target)
(2)利用Proxy.newProxyInstance(arg1,arg2,arg3)生成代理类proxy(参数arg1为类加载器,一般使用this.geClass.getClassLoading()通过反射获得,参数arg2为所要代理对象的接口,一般用target.getClass.getInterfaces()获取,参数arg3为InvocationHandler,可以直接用this)
(3)根据需求在invoke方法调用method.invoke(target,args)前后加入自己想要加入的增强方法
2、测试
(1)生成需要代理的类
(2)生成InvocationHandler动态代理类
(3)将需要代理的真实角色设置为target
(4)生成代理类Proxy
(5)Proxy调用方法
所用代码:
public interface UserService {
void add();
void delete();
void update();
void query();
}
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("调用了add方法");
}
public void delete() {
System.out.println("调用了delete方法");
}
public void update() {
System.out.println("调用了update方法");
}
public void query() {
System.out.println("调用了query方法");
}
}
public class ProxyInvocationHandle 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());//加入的增强方法,利用反射获取method名字
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
测试代码
public class ProxyTest {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();//创建真实角色
ProxyInvocationHandle handle = new ProxyInvocationHandle();//创建代理角色
handle.setTarget(userService);//设置要代理的角色
UserService proxy = (UserService) handle.getProxy();//动态生成代理类
proxy.add();//调用方法
}
}
测试结果: