Spring的AOP开发-AOP简介

目录

AOP简介

AOP概念

AOP思想的实现方案

模拟AOP的基础代码

AOP相关概念


AOP简介

AOP概念

  • AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的生化,OOP是纵向对一个事务的抽象,一个对象包括静态的信息属性,包括动态的方法信息等。而AOP是横向对不同事务的抽象,属性与属性(多个对象的属性进行抽取)、方法与方法(多个对象的方法进行抽取)、对象与对象(多个对象进行抽取)都可成为一个切面,而用这种思维去设计编程的方法叫做面向切面编程。

AOP思想的实现方案

  • 动态代理技术(Proxy),在运行期间,对目标对象的方法进行增强,代理对象同名方法内可以执行原有逻辑的同时嵌入执行其它增强逻辑或其它对象的方法,关于proxy代理的文章,可参考:Java高级-代理(proxy)-CSDN博客

模拟AOP的基础代码

  • 在Spring框架中对于bean对象的增强主要是通过后处理器使用AOP思想来进行实现的,在后处理器中使用代理对象对目标对象进行增强,然后将增强后的代理对象放入单例池中。

  • 具体的示例代码如下
    *

    java 复制代码
    package com.example.Processor;
    
    import com.example.advice.MyAdvice;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    @Component
    public class MockAopBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
        private ApplicationContext applicationContext;
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            // 目的:对UserServiceImpl中的show1和show2方法进行增强,增强的方法存在于MyAdvice中
            // 问题:设定增强范围(判断语句)、如何获取MyAdvice(从Spring容器中获取)
            if (bean.getClass().getPackage().getName().equals("com.example.Service.ServiceImpl")) {
                // 生成当前Bean的Proxy对象
                Object beanProxy = Proxy.newProxyInstance(
                        bean.getClass().getClassLoader(),
                        bean.getClass().getInterfaces(),
                        (Object proxy, Method method, Object[] args) -> {
                            // 执行增强对象的before方法
                            MyAdvice myAdvice = applicationContext.getBean(MyAdvice.class);
                            myAdvice.beforeAdvice();
                            // 执行目标对象的目标方法
                            Object result = method.invoke(bean, args);
                            // 执行增强对象的after方法
                            myAdvice.afterAdvice();
                            return result;
                        }
                );
                return beanProxy;
            }
            return bean;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }

    上述代码是实现bean对象增强的核心过程,指定了需要增强bean对象的范围,以及具体的增强逻辑。实现的两个接口作用具体参照文章:SpringBean的生命周期-CSDN博客

    • 目标对象
      *

      java 复制代码
      package com.example.Service.ServiceImpl;
      
      import com.example.Service.UserService;
      import org.springframework.stereotype.Service;
      
      @Service
      public class UserServiceImpl implements UserService {
          @Override
          public void show1() {
              System.out.println("show1.....");
          }
      
          @Override
          public void show2() {
              System.out.println("show2.....");
          }
      }
    • 通知类

      java 复制代码
      package com.example.advice;
      
      
      import org.springframework.stereotype.Component;
      
      // 自定义增强类,内部提供增强方法
      @Component("myAdvice")
      public class MyAdvice {
          public void beforeAdvice() {
              System.out.println("前置增强");
      
          }
      
          public void afterAdvice() {
              System.out.println("后置增强");
      
          }
      }
    • 测试类

      java 复制代码
      package com.example.Test;
      
      
      import com.example.Service.UserService;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestMyAOP {
          public static void main(String[] args) {
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
              UserService userService = applicationContext.getBean(UserService.class);
              userService.show1();
          }
      }
    • 运行结果

ps:在上述举例代码中,我是在Spring框架下使用注解的的方式进行bean对象的注册,同时需要在配置文件中设置组件扫描的范围,以此让注解进行生效 当然你也可以使用xml配置文件的方式,将对应类的bean对象交给Spring容器管理,具体如何实现可以参考我的往期Spring注解开发、基于Xml方式配置Bean的相关文章

AOP相关概念

概念 描述
切面(Aspect) 增强和切入点的代码组合
连接点(Joinpoint) 目标对象可以被增强的方法
通知/增强(Advice) 增强部分的代码逻辑
切点(切入点)(Pointcut) 目标对象中实际 被增强的方法,连接点包括切点。
引入(Introduction) 在不修改类代码的前提下,引入新的接口和功能。
织入(Weaving) 把切面(增强和切入点代码的组合)应用到目标对象并创建新的代理对象的过程。
目标对象(Target Object) 被增强的方法所在的对象
代理对象(Proxy) 对目标对象增强后的对象,客户端实际调用的对象
相关推荐
最初的↘那颗心2 小时前
Java泛型深度解析:从基础语法到高级应用
java·面向对象·泛型
仙俊红2 小时前
Spring Boot `@Configuration` 与 `@Component` 笔记
java·spring boot·笔记
快乐就是哈哈哈4 小时前
《一文带你搞懂ElasticSearch:从零到上手搜索引擎》
后端·elasticsearch
大鸡腿同学5 小时前
身弱:修炼之路
后端
bobz9655 小时前
cpu 调度 和 gpu 调度
后端
AirMan5 小时前
深入揭秘 ConcurrentHashMap:JDK7 到 JDK8 并发优化的演进之路
后端·面试
bobz9655 小时前
Linux CPU 调度模型
后端
计算机学姐5 小时前
基于SpringBoot的社团管理系统【2026最新】
java·vue.js·spring boot·后端·mysql·spring·mybatis
天上掉下来个程小白5 小时前
微服务-25.网关登录校验-网关传递用户到微服务
java·数据库·微服务
青鱼入云6 小时前
spring如何通过实现BeanPostProcessor接口计算并打印每一个bean的加载耗时
spring