Spring的AOP前置知识点(代理模式)

    科技2023-09-30  82

    为什么要学习代理模式?因为这就是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();//调用方法 } }

    测试结果:

     

    Processed: 0.010, SQL: 8