zoukankan      html  css  js  c++  java
  • Spring之AOP

    Spring之AOP

    面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻 辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。

    AOP底层原理

    JDK动态代理

    cglib动态代理

    AOP(JDK 动态代理)

    创建接口,定义方法

    public interface UserDao {
        public int add(int a, int b);
    
        public String update(String id);
    
    }

    创建接口实现类,实现方法

    public class UserDaoImpl implements UserDao {
        @Override
        public int add(int a, int b) {
            return a + b;
        }
    
        @Override
        public String update(String id) {
            return id;
        }
    }

    使用Proxy类创建接口代理对象

    public class JDKProxy {
        public static void main(String[] args) {
            Class[] interfaces = {UserDao.class};
            UserDaoImpl userDao = new UserDaoImpl();
    
            UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
            int add = dao.add(1, 2);
            System.out.println("result=" + add);
        }
    }
    
    class UserDaoProxy implements InvocationHandler{
    
        //创建的是谁的对象,把谁传递过来
        private Object obj;
        public UserDaoProxy(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("方法执行之前---" + method.getName() + "---传递的参数:" + Arrays.toString(args));
            Object invoke = method.invoke(obj, args);
            System.out.println("方法执行之后");
            return invoke;
        }
    }

    AOP术语

    连接点

    类里面,哪些方法可以被增强,这些方法被称为连接点。

    切入点

    实际被真正增强的方法,成为切入点。

    通知(增强)

    实际增强的逻辑部分称为通知(增强)

    通知有多种类型

    前置通知

    后置通知

    环绕通知

    异常通知

    最终通知

    切面

    是动作,把通知应用到切入点的过程。

    AOP操作

    Spring框架一般都是基于AspectJ实现AOP操作。AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spirng框架一起使用,进行AOP操作。

    AOP相关依赖

    切入点表达式

    切入点表达式作用:知道对哪个类里面的哪个方法进行增强

    语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

    举例 1

    对cn.xupengzhuang.spring5.dao.UserDao类里面的 add 进行增强

    execution(* cn.xupengzhuang.spring5.dao.UserDao.add(..))

    举例 2

    对cn.xupengzhuang.spring5.dao.UserDao类里面的所有的方法进行增强

    execution(* cn.xupengzhuang.spring5.dao.UserDao.* (..))

    举例 3

    对 cn.xupengzhuang.spring5.dao.UserDao 包里面所有类,类里面所有方法进行增强

    execution(* cn.xupengzhuang.spring5.dao.*.* (..))

    AOP 操作(AspectJ 注解)

    创建被增强类

    @Component
    public class UserDao {
        public void add(){
            System.out.println("dao add");
        }
    }

    创建增强类

    @Component
    @Aspect //生成代理对象
    public class UserDaoProxy {
    
        //相同切入点抽取
        @Pointcut(value = "execution(* cn.xupengzhuang.spring5.aop.dao.UserDao.add(..))")
        public void pointdemo() {
        }
    
    
        //前置通知
        @Before(value = "pointdemo")
        public void before() {
            System.out.println("before.........");
        }
    
        //后置通知(返回通知)
        @AfterReturning(value = "pointdemo")
        public void afterReturning() {
            System.out.println("afterReturning.........");
        }
    
        //最终通知
        @After(value = "pointdemo")
        public void after() {
            System.out.println("after.........");
        }
    
        //异常通知
        @AfterThrowing(value = "pointdemo")
        public void afterThrowing() {
            System.out.println("afterThrowing.........");
        }
    
        //环绕通知
        @Around(value = "pointdemo")
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws
                Throwable {
            System.out.println("环绕之前.........");
            //被增强的方法执行
            proceedingJoinPoint.proceed();
            System.out.println("环绕之后.........");
        }
    }

    xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!-- 开启注解扫描 -->
        <context:component-scan base-package="cn.xupengzhuang.spring5.aop"></context:component-scan>
    
        <!-- 开启 Aspect 生成代理对象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    </beans>

    纯注解方式

    @Configuration
    @ComponentScan(basePackages = {"cn.xupengzhuang.spring5"})
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    public class ConfigAop {
    }
  • 相关阅读:
    python库--pandas--Series.str--字符串处理
    前端--jstree--异步加载数据
    python库--flask--创建嵌套蓝图
    Git--生成公钥和私钥并添加gitlab访问权限
    es查询--请求body
    python生成时间序列(date_range)
    golang使用组合完成伪继承
    golang interface类型的动态绑定
    ruby环境安装草稿
    openfire
  • 原文地址:https://www.cnblogs.com/beanbag/p/13460013.html
Copyright © 2011-2022 走看看