spring 日志切面

tech2022-09-17  105

 @Componet 标识一个类为组件,能被spring 扫描到。

@Aspectj 标识类为一个切面

@Order(2) 切面类执行的优先级,即执行顺序,order后数字越小,优先级越高

声明切入点表达式:

@Pointcut ("execution(* com.yw.spring.annotation.*.*(..))"

public void declarePointCut(){}

 @After("execution(* com.yw.spring.aspectJ.annotation.*.*(..))")就可以用 @After("declarePointCut()") 代替。

 

package com.yw.spring.aspectJ.annotation; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * 日志切面 */ @Component //标识为一个组件 @Aspect //标识为一个切面 @Order(2) // 切面类执行的优先级,即执行顺序,order后数字越小,优先级越高 public class LoggingAspect { /** * 声明切入点表达式 */ @Pointcut("execution(* com.yw.spring.aspectJ.annotation.*.*(..))") public void declarePointCut() {} /** * 前置通知: 在目标方法(连接点)执行之前执行. */ @Before("execution(public int com.yw.spring.aspectJ.annotation.ArithmeticCalculatorImpl.add(int,int))") public void beforeMethod(JoinPoint joinPoint) { //获取方法的参数 Object [] args = joinPoint.getArgs(); //方法的名字 String methodName = joinPoint.getSignature().getName(); System.out.println("LoggingAspect==> The method "+methodName+" begin with "+ Arrays.asList(args)); } /** * 后置通知: 在目标方法执行之后执行, 不管目标方法有没有抛出异常. 不能获取方法的结果 * * com.yw.spring.aspectJ.annotation.*.*(..) * * : 任意修饰符 任意返回值 * * : 任意类 * * : 任意方法 * ..: 任意参数列表 * * 连接点对象: JoinPoint */ //@After("execution(* com.yw.spring.aspectJ.annotation.*.*(..))") @After("declarePointCut()") public void afterMethod(JoinPoint joinPoint) { //方法的名字 String methodName = joinPoint.getSignature().getName(); System.out.println("LoggingAspect==> The method " + methodName +" ends ."); } /** * 返回通知: 在目标方法正常执行结束后执行. 可以获取到方法的返回值. * * 获取方法的返回值: 通过returning 来指定一个名字, 必须要与方法的一个形参名一致. */ //@AfterReturning(value="execution(* com.yw.spring.aspectJ.annotation.*.*(..))",returning="result") @AfterReturning(value="declarePointCut()",returning="result") public void afterReturningMethod(JoinPoint joinPoint,Object result ) { //方法的名字 String methodName = joinPoint.getSignature().getName(); System.out.println("LoggingAspect==> The method " + methodName + " end with :" + result ); } /** * 异常通知: 在目标方法抛出异常后执行. * * 获取方法的异常: 通过throwing来指定一个名字, 必须要与方法的一个形参名一致. * * 可以通过形参中异常的类型 来设置抛出指定异常才会执行异常通知. * */ @AfterThrowing(value="execution(* com.yw.spring.aspectJ.annotation.*.*(..))",throwing="ex") public void afterThrowingMethod(JoinPoint joinPoint,ArithmeticException ex ) { //方法的名字 String methodName = joinPoint.getSignature().getName(); System.out.println("LoggingAspect==> Thew method " + methodName + " occurs Exception: " +ex ); } /** * 环绕通知: 环绕着目标方法执行. 可以理解是 前置 后置 返回 异常 通知的结合体,更像是动态代理的整个过程. */ @Around("execution(* com.yw.spring.aspectJ.annotation.*.*(..))") public Object aroundMethod(ProceedingJoinPoint pjp) { //执行目标方法 try { //前置 Object result = pjp.proceed(); //返回 return result ; } catch (Throwable e) { //异常通知 e.printStackTrace(); }finally { // 后置 } return null; } }

base-package: 扫描的基本包路径

annotation-config: 是否激活属性注入注解.<context:component-scan>元素也完成了<context:annotation-config>元素的工                                   作, 开关就是这个属性,false则关闭属性注入注解功能

name-generator=

                     "org.springframework.context.annotation.AnnotationBeanNameGenerator" :

                        Bean的ID策略生成器, 默认是类名首字符小写的策略。也可自定义。                         org.springframework.beans.factory.support.DefaultBeanNameGenerator生成器,                       它为了防止Bean的ID重复,它的生成策略是类路径+分隔符+序号,这个生成器不支持自定义ID,否则抛出异常。

   resource-pattern="**/*.class" :对资源进行筛选的正则表达式,这边是个大的范畴,                                    具体细分在include-filter与exclude-filter中进行。

   scope-resolver="org.springframework.context.annotation                        .AnnotationScopeMetadataResolver": scope解析器 ,与scoped-proxy只能同时配置一个

   scoped-proxy="no" :scope代理,与scope-resolver只能同时配置一个                        scope代理,有三个值选项,no(默认值),interfaces(接口代理),targetClass(类代理),                        那什么时候需要用到scope代理呢,举个例子,我们知道Bean的作用域scope有singleton,                        prototype,request,session,                        那有这么一种情况,当你把一个session或者request的Bean注入到singleton的Bean中时,                        因为singleton的Bean在容器启动时就会创建A,而session的Bean在用户访问时才会创建B,                        那么当A中要注入B时,                        有可能B还未创建,这个时候就会出问题,那么代理的时候来了,B如果是个接口,                        就用interfaces代理,是个类则用targetClass代理。

   use-default-filters="false": 是否使用默认的过滤器,默认值true                                注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,                                    不然会“失效”,被默认的过滤机制所覆盖                                注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter                                里的内容进行排除.                              过滤器类型          描述                                annotation   过滤器扫描使用注解所标注的那些类,通过expression属性指定要扫描的注释                                assignable   过滤器扫描派生于expression属性所指定类型的那些类                                aspectj      过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类                                custom       使用自定义的org.springframework.core.type.TypeFliter实现类,该类由                                              expression属性指定                                regex        过滤器扫描类的名称与expression属性所指定正则表示式所匹配的那些类

 

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <!-- 组件扫描 --> <context:component-scan base-package="com.atguigu.spring.aspectJ.annotation"></context:component-scan> <!-- 基于注解使用AspectJ: 主要的作用是为切面中通知能作用到的目标类生成代理. --> <aop:aspectj-autoproxy/> </beans>

 

最新回复(0)