SSM3==静态代理、动态代理、cglib代理理解==通过XML配置spring AOP,通过注解配置spring AOP

SSM3==静态代理、动态代理、cglib代理理解==通过XML配置spring AOP,通过注解配置spring AOP,第1张

SSM3==静态代理、动态代理、cglib代理理解==通过XML配置spring AOP,通过注解配置spring AOP
静态代理:
为什么要代理?在不改动原代码的基础上,丰富调用某个方法时实现的功能。
比如service类中原本update只会更新,但是通过代理类加上了判断权限和输出时间的功能。
其实这些功能也可以写在原代码的类里,那为什么不这样写,而要多此一举的写在代理类里呢?
因为这些功能是根据实际情况经常需要变动的!!!写在代理类里,解耦,方便更改!

静态代理模式在不改变目标对象的前提下,实现了对目标对象的功能扩展。
不足:静态代理实现了目标对象的所有方法,一旦目标接口增加方法,代理对象和目标对象都要进行相应的修改,增加维护成本。

==============================================================

动态代理:

        根据上述静态代理的不足,怎么解决?我们自己也可以解决,无非是根据根据想要代理的类,通过反射获得他所有的方法名,然后在方法被调用前后分别插入一些 *** 作,这就叫做动态代理!java官方给我提供了实现上述 *** 作的一个接口,叫做的InvocationHandler接口,其实这个接口也就是通过反射获取需要代理类的方法Method,然后在method.invoke(target)调用前、调用后加上我们自定义的 *** 作。

       不足:

  • JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。
    如果想代理没有实现接口的类,就可以使用CGLIB实现。
package com.ldj.proxy.demo.动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//想实现动态代理,只需要实现Java提供的InvocationHandler接口,其实这个接口也就是通过反射获取需要代理类的方法名,然后在这些方法被调用前加上我们自定义的 *** 作
public class AdminServiceInvocation  implements InvocationHandler {

    private Object target;

    public AdminServiceInvocation(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("在这书写被代理的对象方法被执行之前需要做的 *** 作。判断用户是否有权限进行 *** 作");
        Object obj = method.invoke(target);//通过反射执行被代理对象原本的方法
        System.out.println("在这书写被代理的对象方法被执行之后需要做的 *** 作。记录用户执行 *** 作的用户信息、更改内容和时间等");
        return obj;
    }
}

      回顾下java的反射:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class e_反射获取成员方法并调用 {
    //Method[] getMethods()返回所有公共成员方法对象的数组,包括继承的
    //Method[] getDeclaredMethods()返回所有成员方法对象的数组,不包括继承的
    //Method getMethod(String name, Class...parameterTypes)返回单个公共成员方法对象
    //Method getDeclaredMethod(String name, Class...parameterTypes)返回单个成员方法对象
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        System.out.println("/================================================");
        Class clazz = Class.forName("Student");
        Method study = clazz.getMethod("study");//获取public空参成员方法
        System.out.println(study);

        System.out.println("/================================================");
        Method study1 = clazz.getMethod("study", String.class);//获取public带参成员方法
        System.out.println(study1);

        System.out.println("/================================================");
        Method hide = clazz.getDeclaredMethod("hide");//获取private私有空参成员方法
        System.out.println(hide);

        //获取成员方法并调用
        System.out.println("/================================================");
        Method study2 = clazz.getMethod("study2", String.class);
        Object res = study2.invoke(clazz.getConstructor().newInstance(), "aaaaa");
        System.out.println(res);
    }
}

======================================================

cglib代理:

        

 cglib参考文章https://segmentfault.com/a/1190000011291179https://segmentfault.com/a/1190000011291179

  其实实现都是一样的,通过代理类在原方法执行前后增加一些 *** 作:

 ========================================================================

        如上,了解三种实现代理的方式,那么spring AOP功能如何实现?spring的AOP默认采用的就是如上述的动态代理!当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可通过设置强制使用CGLIB,而且spring-aspect包内部默认自带cglib的依赖。

        spring通过XML实现AOP是怎么实现的呢?参考下文

Spring系列(四):Spring AOP详解和实现方式(xml配置和注解配置) - 小不点啊 - 博客园参考文章:http://www.cnblogs.com/hongwz/p/5764917.html 一、什么是AOP AOP(Aspect Oriented Programming),即面向切面编程,https://www.cnblogs.com/leeSmall/p/7667040.html        完成的项目结构如下:

               

 

        ·接下来用纯注解实现AOP

通知:加什么?

切入点:加在哪?

接入点:能够加在哪?

配置类上书写@EnableAspectJAutoProxy

AOP切入点表达式:标准格式,接口的方法、实现类的方法、通配符

AOP通知类型5种:......

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5137207.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存