首页 > 其他分享 >spring原理(第十一天)

spring原理(第十一天)

时间:2024-08-07 19:25:44浏览次数:13  
标签:第十一天 spring System 切面 原理 println new class out

从 @Aspect 到 Advisor

代理创建器

准备好两种切面

 static class Target1 {
        public void foo() {
            System.out.println("target1 foo");
        }
    }

    static class Target2 {
        public void bar() {
            System.out.println("target2 bar");
        }
    }

    @Aspect // 高级切面类
    @Order(1)
    static class Aspect1 {
        @Before("execution(* foo())")
        public void before1() {
            System.out.println("aspect1 before1...");
        }

        @Before("execution(* foo())")
        public void before2() {
            System.out.println("aspect1 before2...");
        }
    }

    @Configuration
    static class Config {
        @Bean // 低级切面
        public Advisor advisor3(MethodInterceptor advice3) {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression("execution(* foo())");
            DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3);
            return advisor;
        }
        @Bean
        public MethodInterceptor advice3() {
            return invocation -> {
                System.out.println("advice3 before...");
                Object result = invocation.proceed();
                System.out.println("advice3 after...");
                return result;
            };
        }
    }

创建容器,并添加beanfactory后处理器解析bean注解,和aspect注解

        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("aspect1", Aspect1.class);
        context.registerBean("config", Config.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        // BeanPostProcessor
        // 创建 -> (*) 依赖注入 -> 初始化 (*)

        context.refresh();

 第一个重要方法 findEligibleAdvisors 找到有【资格】的 Advisors
                a. 有【资格】的 Advisor 一部分是低级的, 可以由自己编写, 如下例中的 advisor3
                b. 有【资格】的 Advisor 另一部分是高级的, 由本章的主角解析 @Aspect 后获得

        AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
        List<Advisor> advisors = creator.findEligibleAdvisors(Target2.class, "target2");

 第二个重要方法 wrapIfNecessary
                a. 它内部调用 findEligibleAdvisors, 只要返回集合不空, 则表示需要创建代理

        Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1");
        System.out.println(o1.getClass());
        Object o2 = creator.wrapIfNecessary(new Target2(), "target2", "target2");
        System.out.println(o2.getClass());

        ((Target1) o1).foo();

此时o1创建出来的就是代理对象,o2就是本身

学到了什么
            a. 自动代理后处理器 AnnotationAwareAspectJAutoProxyCreator 会帮我们创建代理
            b. 通常代理创建的活在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行
            c. 高级的 @Aspect 切面会转换为低级的 Advisor 切面, 理解原理, 大道至简

代理创建时机

                a. 代理的创建时机
                    1. 初始化之后 (无循环依赖时)
                    2. 实例创建后, 依赖注入前 (有循环依赖时), 并暂存于二级缓存
                b. 依赖注入与初始化不应该被增强, 仍应被施加于原始对象

高级切面转低级切面(@Before 对应的低级通知 )

        AspectInstanceFactory factory = new SingletonAspectInstanceFactory(new Aspect());
        // 高级切面转低级切面类
        List<Advisor> list = new ArrayList<>();
        for (Method method : Aspect.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Before.class)) {
                // 解析切点
                String expression = method.getAnnotation(Before.class).value();
                AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
                pointcut.setExpression(expression);
                // 通知类
                AspectJMethodBeforeAdvice advice = new AspectJMethodBeforeAdvice(method, pointcut, factory);
                // 切面
                Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
                list.add(advisor);
            }
        }
  1. @Before 前置通知会被转换为原始的 AspectJMethodBeforeAdvice 形式, 该对象包含了如下信息

    1. 通知代码从哪儿来

    2. 切点是什么(这里为啥要切点, 后面解释)

    3. 通知对象如何创建, 本例共用同一个 Aspect 对象

  2. 类似的还有

    1. AspectJAroundAdvice (环绕通知)

    2. AspectJAfterReturningAdvice

    3. AspectJAfterThrowingAdvice (环绕通知)

    4. AspectJAfterAdvice (环绕通知)

 


 

 


 

 

 

标签:第十一天,spring,System,切面,原理,println,new,class,out
From: https://blog.csdn.net/GD2604279407/article/details/140984620

相关文章

  • Springboot计算机毕业设计大学生请假系统(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,学院,专业,班级,请假信息,请假条,销假信息,公告信息,出勤率开题报告内容一、选题背景与意义随着高等教育的普及和学生数量的不断增加,传统的学生请假......
  • Springboot计算机毕业设计大学生档案管理系统-程序+源码
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,学生档案,班级成绩单,登记表,个人荣誉开题报告内容一、研究背景与意义研究背景:随着高等教育的发展,大学生人数的不断增加,学生档案信息的数量急剧增长......
  • Springboot计算机毕业设计打印助手平台21swx
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表打印参数,用户,店铺,打印服务,打印订单开题报告内容一、项目背景与意义随着信息技术的快速发展,企业和校园中的打印服务已成为日常办公和学习中不可或缺的一部分......
  • DockerCompose中使用自定义网络的方式实现部署SpringBoot+Mysql+Redis
    场景Docker中Docker网络-理解Docker0与自定义网络的使用示例:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140788458Docker中使用自定义网络方式实现Redis集群部署与测试流程:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140797109上面介绍了D......
  • springboot实战
    pom<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org......
  • 基于springboot+vue开发的垃圾分类识别系统
    背景随着社会的快速发展,计算机的影响是全面且深入的。日常生活中,“垃圾”无处不在,家庭公寓里的垃圾桶、街头巷尾的垃圾箱、城市郊区的垃圾场、校园的垃圾站点等等,你也常常会发现,垃圾处理时通常有着多种分类,随着垃圾分类的普及,用户的数量和管理员的工作量在不断增加,工作也更......
  • 基于springboot+MySQL校园社团信息管理系统的设计与实现-计算机毕设 附源码 02705
    springboot校园社团信息管理系统的设计与实现目 录摘要1绪论1.1研究背景1.2 研究意义1.3论文结构与章节安排2 校园社团信息管理系统系统分析2.1可行性分析2.2系统流程分析2.2.1数据增加流程2.2.2数据修改流程2.2.3数据删除流程2.3 系统......
  • Spring - 事件监听机制
    Spring-事件监听机制  Spring事件驱动模型也是观察者模式很经典的应用。就是我们常见的项目中最常见的事件监听器。 一、Spring中观察者模式的四个角色 1. 事件-ApplicationEvent ApplicationEvent是所有事件对象的父类。ApplicationEvent继承自jdk的E......
  • 激光点云去畸变_原理及实现
    激光点云去畸变:原理及实现机械式激光雷达产生畸变的原因Lidar扫描周期内(一般0.1s)自车有一定幅度的旋转(Rotation)和平移(Translation),因此不同时间点打出去的激光点束并不在严格统一的Lidar坐标系内,需要对同一帧Lidar转化在统一时间戳对应的Lidar坐标系上(一般转化到第......
  • 2024最新Mysql锁机制与优化实践以及MVCC底层原理剖析
    锁机制详解锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供需要用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一......