自学内容网 自学内容网

Spring之AOP入门

1.AOP介绍

AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构,作用是在不改动原始设计的基础上为其进行功能增强

2.AOP的核心概念

概念定义SpringAOP(注解开发)中的具体形式
连接点(JoinPoint)程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等执行方法
切入点(PointCut)匹配连接点的式子一个切入点可以只描述一个方法,也可以匹配多个方法
通知(Advice)在切入点处执行的操作,也就是共性功能以方法的形式呈现
切面(Aspect)描述通知与切入点的对应关系@Aspect 、@Before、@After、@Around、@AfterReturning、@AfterThrowing等注解

3.SpringAOP的使用步骤

(1)导入SpringAOP依赖坐标
注:spring-context中包含AOP相关依赖

 <!--spring-context-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.0.RELEASE</version>
    </dependency>
    <!--aspect-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>

(2)定义连接点

package com.example.service;

public interface IUser {
    void eat();
    void sleep();
}
package com.example.service.impl;

import com.example.service.IUser;
import org.springframework.stereotype.Service;

@Service
public class UserImpl implements IUser {
    @Override
    public void eat() {
        System.out.println("炫饭中... ...");
    }

    @Override
    public void sleep() {
        System.out.println("深度睡眠中... ...");
    }
}

(3)定义通知类,制作通知

package com.example.aop;

public class MyAdvice {
    public void advice(){
        System.out.println("在连接点之前执行的共性功能");
    }
}

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

package com.example.aop;

import org.aspectj.lang.annotation.Pointcut;

public class MyAdvice {
    @Pointcut("execution(void com.example.service.IUser.eat())")
    private void pt(){}

    public void advice(){
        System.out.println("在连接点之前执行的共性功能");
    }
}

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

package com.example.aop;

import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

public class MyAdvice {
    @Pointcut("execution(void com.example.service.IUser.eat())")
    private void pt(){}

    @Before("pt()")
    public void advice(){
        System.out.println("在连接点之前执行的共性功能");
    }

}

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

package com.example.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect// 代表这个类是一个切面
public class MyAdvice {
    @Pointcut("execution(void com.example.service.IUser.eat())")
    private void pt(){}

    @Before("pt()")
    public void advice(){
        System.out.println("在连接点之前执行的共性功能");
    }
}

(7)开启Spring对AOP注解驱动支持

package com.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy// 开启Spring对AOP注解驱动支持
public class SpringConfig {
}

4.SpringAOP的工作流程

(1)Spring容器启动
(2)读取所有切面配置中的切入点
(3)初始化Bean,判定Bean对应的类中的方法是否匹配到任意切入点

  • 匹配失败,创建对象
  • 匹配成功,创建原始对象(目标对象)的代理对象

(4)获取Bean执行方法

  • 获取Bean,调用方法并执行,完成操作(对应步骤(3)匹配失败的情况)
  • 获取的Bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作(对应步骤(3)匹配成功的情况)

原文地址:https://blog.csdn.net/Lyhdreamer/article/details/135930647

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!