栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring AOP

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring AOP

什么是AOP
  • AOP Aspect Oriented Programing 面向切面编程
  • AOP采用横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全性检查、缓存)

  • Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AOP相关术语
  • Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
  • Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
  • Advice(增强/通知):所谓通知是指拦截到Joinpoint之后所要做的事情。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
  • Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态添加一些方法或者Field
  • Target(目标对象):代理的目标对象
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类加载期织入
  • Proxy(代理):一个类被AOP织入增强后,就产生了一个结果代理类
  • Aspect(切面):是窃读点和通知(引介)的结合
AOP底层实现 JDK动态代理

只能增强实现了接口的类

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

public class MyJdkProxy implements InvocationHandler {
    private UserDao userDao;

    public MyJdkProxy(UserDao userDao){
        this.userDao = userDao;
    }

    public Object createProxy() {
        return Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("    权限校验");
            return method.invoke(userDao , args);
        }
        return method.invoke(userDao , args);
    }
}

使用CGLIB生成代理
  • 对于不使用接口的业务类,无法使用JDK动态代理
  • CGlib采用非常底层字节码技术,可以为一个类创建子类,解决无接口代理问题
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyCglibProxy implements MethodInterceptor {
    private ProductDao productDao;

    public MyCglibProxy(ProductDao productDao){
        this.productDao = productDao;
    }

    public Object createProxy(){
        //1.创建核心类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(productDao.getClass());
        //3.设置回调
        enhancer.setCallback(this);
        //4.生成代理
        Object proxy = enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验");
            return methodProxy.invokeSuper(proxy , args);
        }
        return methodProxy.invokeSuper(proxy , args);
    }
}

代理知识总结
  • Spring在运行期,生成动态代理对象,不需要特殊的编译器
  • Spring AOP的底层就是通过JDK动态代理或CGLib动态代理技术,为目标Bean执行横向织入
    1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理
    2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类
  • 程序中应优先对接口创建代理,便于程序解耦维护
  • 标记为final的方法,不能被代理,因为无法进行覆盖
    1.JDK动态代理,是针对接口生成子类,接口中方法不能使用final修饰
    2.CGLib是针对目标类生成子类,因此类或方法不能使用final
  • Spring只支持方法的连接点,不提供属性的连接点
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/297987.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号