你会使用面向切面编程吗(springboot超详细)?

springboot中如何面向切面编程?

  • 一.什么是面向切面编程
  • 二.AOP中的几个术语
        • 1. 连接点
        • 2. 切入点
        • 3. 通知(增强)
        • 4. 切面
        • 5.切入点表达式
        • 举例
  • 三.如何使用
        • 1.首先肯定是要引入相关依赖啦!!
        • 2.然后创建一个增强类
        • 3.之后就是写扩展的方法了

一.什么是面向切面编程

面向切面编程(AOP):利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

简单点理解就是:不通过修改源代码方式,在主干功能里面添加新功能

AOP的底层使用的是动态代理方式;

二.AOP中的几个术语

1. 连接点

连接点指的是哪些方法可以被增强,这些方法称为连接点

2. 切入点

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

3. 通知(增强)

实际增强的逻辑部分(扩展的功能)称为通知或增强
通知有多种类型你会使用面向切面编程吗(springboot超详细)?_第1张图片

4. 切面

把通知应用到切入点的过程

5.切入点表达式

  • 切入点表达式作用:

知道对哪个类里面的方法进行增强

  • 语法结构

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

举例

  • 对com.atguigu.dao.BookDao类里面的add进行增强
    execution(* com.atguigu.dao.BookDao.add(…))

  • 对com.atguigu.dao.BookDao类里面的所有的方法进行增强
    execution(* com.atguigu.dao.BookDao.* (…))

  • 对com.atguigu.dao包里面所有类,类里面所有方法进行增强
    execution(* com.atguigu.dao.. (…))

权限修饰符可省略,
返回类型用通配符*代替
(…) 代表可变参数

三.如何使用

1.首先肯定是要引入相关依赖啦!!

	<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-aopartifactId>
	dependency>

2.然后创建一个增强类

@Aspect
@Component
public class HttpAspect {

}

要加上@Aspect注解和@Component注解

3.之后就是写扩展的方法了

这里介绍几个常见的通知

  • @Before 前置通知

在访问到目标方法(add)方法之前,先执行此方法;
在此方法中可以获取request对象,获取请求的URL,请求方法,ip,类方法,请求参数

private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
//这里定义looger,为了后面使用日志进行记录

@Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") 
public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();//获取request
        HttpServletRequest request = attributes.getRequest();
        //url
        logger.info("url={}", request.getRequestURL());
        //method
        logger.info("method={}", request.getMethod());
        //ip
        logger.info("ip={}", request.getRemoteAddr());
        //类方法
        logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        //参数
        logger.info("args={}", joinPoint.getArgs());
    }

注意:

如果要获取请求方法和参数,需要传入JoinPoint作为形参

  • @After 后置通知(又称最终通知)
    在访问目标方法结束之后,再执行此方法;
@After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") 
	public void after() { 
	System.out.println("after.........");
}
  • @AfterReturning 返回通知(后置通知)

在目标方法返回对象之后,此方法接收返回值;

@AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        logger.info("response={}", object.toString());
    }
  • @AfterThrowing 异常通知
    在发生异常后执行
@AfterThrowing(value="execution(*com.atguigu.spring5.aopanno.User.add(..))") 
	public void afterThrowing() { 
	System.out.println("afterThrowing........."); 
}
  • @PointCut 相同切入点的抽取
    我们可以把相同的切入点抽取出来,减少重复代码的开发
//抽取切入点
@Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void pointdemo() { 
} 

//前置通知 
@Before(value = "pointdemo()") 
	public void before() {
	System.out.println("before.........");
 }

你可能感兴趣的:(springboot,java,spring)