springboot中两种方式配置切面

在工作中做项目微服务化,需要把原来老的项目拆分成一个个小的接口对外提供服务。对拆分出来的接口,需要做权限控制与入参,出参,耗时等日志记录。于是做个了切面类,来通过切面对相应方法做记录。

1.首先我们需要引入相应的jar包
 

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

 

 

 

2.找一个你需要做切面拦截的接口

例如我想对下图中的testProxy()方法做切面拦截,记录日志信息:

package com.example.demo.service.impl;

import java.util.Date;

import org.springframework.stereotype.Service;

@Servicepublic class TestAspectServiceImpl {
    public String testAspect(String str) {
        System.out.println("========" + new Date().getTime() + "===========");
        return str + "yes";
    }
}

 

 

 

 

 

 

2.1.1接着开始写切面类

在这里我们对需要控制的接口做了出参和入参进行日志记录:

package com.example.demo.aspect;

import java.util.Arrays;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TestAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger( TestAspect.class );
    @Around( value = "(execution(* com.example.demo.service.impl..*.*(..)))" )
    public Object service( ProceedingJoinPoint joinPoint ) {
        String method = joinPoint.getTarget().getClass().getSimpleName() + "." + joinPoint.getSignature().getName() + "(..)";
        // 调用接口方法
        Object response = null;
        try {
            LOGGER.info( "Service start. method : {} , Param : {}", method, Arrays.toString(joinPoint.getArgs()) );
            response = joinPoint.proceed();
            LOGGER.info( "Service finish. method : {}, Result : {}", method, response );
        } catch( Throwable e ) {
            LOGGER.error( "Service error. method : {} , Cause : {}", method, e );
        } finally {
            //ThreadContext.serialDestroy();
        }
        return response;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

execution(* com.example.demo.service.impl..*.*(..))

execution()是最常用的切点函数,其语法如下所示: 整个表达式可以分为五个部分:

 1、execution(): 表达式主体。

 2、第一个*号:表示返回类型,*号表示所有的类型。

 3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.example.demo.service.impl包、子孙包下所有类的方法。

 4、第二个*号:表示类名,*号表示所有的类。

 5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

 

2.1.2编写测试类

@Test
    public void ProxyServiceImplTest() {
        testAspectServiceImpl.testAspect("isAspect?");
    }

 

 

 

 

单元测试结果为,可以看到切面打印了入参与出参:

com.example.demo.aspect.TestAspect       : Service start. method : TestAspectServiceImpl.testAspect(..) , Param : [isAspect?]
========1552894755581===========
com.example.demo.aspect.TestAspect       : Service finish. method : TestAspectServiceImpl.testAspect(..), Result : isAspect?yes

 

 

 

这里是直接根据描述的路径去找到想要增加切面的方法,如果我们想个性化,可以通过在方法上增加标签,即可实现对该方法的切面工作。

2.2.1自定义标签

package com.example.demo.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//声明注解的保留期限
@Retention(RetentionPolicy.RUNTIME)
//声明可以使用该注解的目标类型
@Target(ElementType.METHOD)
@Documented
public @interface Authority {
    // 声明注解成员
    boolean value() default false;
}

 

 

 

 

 

 

 

 

 

2.2.2标签切面

@Aspect
@Component
public class AuthorityAspect {
    @Around( value = "@annotation(com.example.demo.annotation.Authority)" )
    public Object service(ProceedingJoinPoint joinPoint ){
        Object[] args = joinPoint.getArgs();
        if("y".equals(args[0])) {
            try {
                joinPoint.proceed();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return "yes";
        }
        return "no";
    }


}

 

 

 

 

 

 

 

 

 

 

 

在你所有添加切面的接口中加上注解就可以了

@Service
public class TestAspectServiceImpl {
    @Authority
    public String testAspect(String str) {
        System.out.println("========" + new Date().getTime() + "===========");
        return str + "yes";
    }
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值