Spring之AOP简单讲解

本文深入讲解了Spring的AOP(面向切面编程),包括基本概念、案例演示、相关概念、工作流程、核心概念、切入点表达式、xml配置方式以及AOP在不同场景的应用。通过对AOP的理解和实践,展示了如何在不改变原有代码的情况下,实现功能的增强和效率的提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一:基本概念

二:案例:模拟AOP的基础代码

三:AOP相关概念

四:AOP入门案例思路分析

五:AOP工作流程

六:AOP核心概念

七:AOP切入点表达式

八:xml方式AOP快速入门

九:案例:测量业务层接口万次执行效率

JoinPoint对象

 十:案例:百度网盘密码数据兼容处理

语法形式不同:

可配置的切面数量不同:

使用场景不同:

xml方式AOP原理剖析

注解方式AOP基本使用

注解方式AOP原理剖析

十一:AOP总结


一:基本概念

               AOP, Aspect Oriented Programming, 面向切面编程,一种编程范式,指导开发者如何组织程序结构, 是对面向对象编程OOP的升华。OOP(Object Oriented Programming)是纵向对一个事物的抽象, 一个对象包括静态的属性信息, 包括动态的方法信息等。而AOP是横向的对不同事物的抽象, 属性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程

        作用:在不惊动原始设计的基础上为其进行功能增强

        Spring理念:无入侵式/无侵入式

 

 

 

 

 

二:案例:模拟AOP的基础代码

               其实在之前学习BeanPostProcessor时, 在BeanPostProcessor的after方法中使用动态代理对Bean进行了增强, 实际存储到单例池singleObjects中的不是当前目标对象本身, 而是当前目标对象的代理对象Proxy, 这样在调用目标对象方法时, 实际调用的是代理对象Proxy的同名方法, 起到了目标方法前后都进行增强的功能,对该方式进行一下优化,将增强的方法提取出去到一个增强类中,且只对com.tangyuan.service.impl包下的任何类的任何方法进行增强

//自定义增强类
  public class My Advice{
        public void beforeAdvice() {
           System.out.println("beforeAdvice...") ;
        }

        public void afterAdvice() {
           System.out.println("afterAdvice...") ;
        }

}

1.创建service类

public interface UserService {
     void show1();
    
     void show2();

}  

2.实现service的实现类

public class UserServiceImpl implements UserService { 
  @Override
    public void show1() {  
          System.out.println(show1.....);
    }

      @Override
    public void show2() {  
          System.out.println(show2.....);
    }


}

ps:以上目标对象,目标类已经准备完成

3.创建增强类,内部提供增强方法

public class MyAdvice{
      //前置增强方法
      public void beforeAdvice(){
            System.out.println(前置的增强.....);
      }
    
     public void afterAdvice(){
            System.out.println(后置的增强.....);
      }    
    
}

目的:在执行show1()方法的同时,也要将before和after的方法执行

4.将UserServiceImpl类和MyAdvic类配置到xml文件Spring容器中

<bean id="userService" class="com.tangyuan.service.impl.UserServiceImpl"></bean>
<bean id="myAdvice" class="com.tangyuan.advice.MyAdvice"></bean>

5.BeanProxy对象创建

 

public class MockAopBeanPostProcessor implements BeanPostProcessor,ApplicationContextAware{
    //成员变量
    private ApplicationContext applicationContext;    
    
      @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
       //目的:对UserServiceImpl中的show1和show2方法进行增强,增强方法存在于MyAdvice类中
        //问题:1.筛选Service,impl包下的所有的类的所有方法都可以进行增强----解决方案if-else
        //2.MyAdvice怎么获取到?解决方案:从Spring容器中获得MyAdvice
        if(bean.getClass().getPackage().getName().equals("com.tangyuan.service.impl")){
            //生成当前bean的Proxy对象
          Object beanProxy=Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (Object proxy,Method  method,Object[] args) -> {
                     MyAdvice myAdvice=applicationContext.getBean(MyAdvice.class);
                    //执行增强对象的before方法
                     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;
    }
    
    

}

6.将 MockAopBeanPostProcessor类配置到xml文件Spring容器中

7.测试

  ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
   IUserService userService = applicationContext.getBean(UserService.class);
        userService.show1();

三:AOP相关概念

 

切入点范围小,连接点范围大,切入点一定在连接点中

 

四:AOP入门案例思路分析

 

目的:在接口执行前输出当前系统时间

开发模式:xml or 注解

思路分析:

1.导入坐标(pom.xml)

 <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
  </dependencies>

 spring-context坐标依赖spring-aop坐标:

2.制作连接点方法(原始操作,Dao接口与实现类)  

public interface BookDao {
    public void save();
    public void update();
}
import com.tangyuan.dao.BookDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

@Repository
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println(System.currentTimeMillis());
        System.out.println("book dao save ...");
    }

    public void update(){
        System.out.println("book dao update ...");
    }

3.制作共性功能(通知类与通知)

     创建一个类,用来存储共性功能

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
    //4.定义切入点
    //设置切入点,要求配置在方法上方
    @Pointcut("execution(void com.tangyuan.dao.BookDao.update())")
    private void pt(){}

     //5.绑定切入点与通知关系(切面)
    //设置在切入点pt()的前面运行当前操作(前置通知)
     @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

 4.定义切入点

     切入点定义依托一个不具有实际意义的方法进行,即无参数,无返回值,方法体无实际逻辑

5.绑定切入点与通知关系(切面),并指定通知添加到原始接点的具体执行位置

6.定义通知类受Spring容器管理,并定义当前类为切面类

7.在配置类中进行相关属性的配置,开启Spring对AOP注解驱动支持

五:AOP工作流程

1.Spring容器启动

2.读取所有切面配置中的切入点


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值