自定义注解+AOP的使用

一、AOP的使用

在 Spring AOP 中,使用 @Around 注解时,你可以通过控制 ProceedingJoinPoint 的执行时机来在方法执行前和执行后分别插入逻辑。

1. 在目标方法执行前插入逻辑
在调用 joinPoint.proceed() 之前编写代码,所有逻辑会在目标方法执行之前执行。

2. 在目标方法执行后插入逻辑

在 joinPoint.proceed() 调用之后编写代码,所有逻辑会在目标方法执行之后执行。

注意:

①调用joinPoint.proceed() ,切面类的代码会阻塞住

②一般切面类返回的是joinPoint.proceed()的返回值

@Aspect
@Component
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 目标方法执行前的操作
        System.out.println("Before method execution: " + joinPoint.getSignature().getName());

        // 调用目标方法
        Object result = joinPoint.proceed();  // 这行代码执行目标方法

        // 目标方法执行后的操作
        System.out.println("After method execution: " + joinPoint.getSignature().getName());

        return result;
    }
}

二、配合AOP用于登录判断

1、创建自定义注解

我们先定义一个自定义注解,在这里的作用是一个标识,真正的逻辑代码在切面类中


/**
 * 自定义登录注解
 */
//登录判断
@Target(ElementType.METHOD) //用于加载方法上面
@Retention(RetentionPolicy.RUNTIME)//运行时执行
public @interface GuiguLogin {
}

2、创建切面类

 使用环绕

@Around("execution(* com.atguigu.daijia.*.controller.*.*(..)) " +
        "&& @annotation(guiguLogin)")

/**
 * 创建切面类
 */
@Component
@Aspect
public class GuiguLoginAspect {
    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 在切入点执行的方法   --这个方法判断用户有没有登录(根据请求头中的token)
     * @param proceedingJoinPoint
     * @param guiguLogin
     * @return
     * @throws Throwable
     */
    //在com.atguigu.daijia.*.controller包下的所有类的所有方法及含有guiguLogin注解进行增强
    @Around("execution(* com.atguigu.daijia.*.controller.*.*(..)) " +
            "&& @annotation(guiguLogin)")
    public Object login(ProceedingJoinPoint proceedingJoinPoint,
                        GuiguLogin guiguLogin)  throws Throwable {

        //1、获取请求头
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes)attributes;
        HttpServletRequest request = sra.getRequest();

        //2、从请求头中获取token
        String token = request.getHeader("token");
        //3、非空判断
        if(!StringUtils.hasText(token)){
            //请求头中没有token,未登录
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }

        //4、根据token从redis中查看用户信息
        String customerId
                = (String) redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);

        if(StringUtils.hasText(customerId)){
            //5、将用户信息放入ThreadLocal
            AuthContextHolder.setUserId(Long.parseLong(customerId));
        }
        //todo 以后看看要不要做非空判断,如果是空就抛出错误




        return proceedingJoinPoint.proceed();//执行业务方法
    }

}

在需要验证登录的代码的地方加上这个自定义注解

注意:

自定义注解配合AOP:适合需要灵活、声明式的方式来管理验证逻辑和切面功能的场景,尤其是当你希望将验证逻辑与业务逻辑分离时。适合复杂的验证需求和统一管理。

拦截器:适合简单、直观的请求处理和验证,特别是当你需要明确控制请求处理的前后顺序时。适合简单场景或者不需要复杂功能扩展的情况。

要通过自定义注解AOP来实现Spring Security配置指定接口不需要Token才能访问,可以按照以下步骤进行操作: 1. 创建一个自定义注解,例如`@NoTokenRequired`,用于标识不需要Token的接口。 ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NoTokenRequired { } ``` 2. 创建一个切面类,用于拦截带有`@NoTokenRequired`注解的方法,并跳过Spring Security的Token验证。 ```java @Aspect @Component public class TokenValidationAspect { @Before("@annotation(com.example.NoTokenRequired)") public void skipTokenValidation(JoinPoint joinPoint) { // 跳过Spring Security的Token验证逻辑 SecurityContextHolder.getContext().setAuthentication(null); } } ``` 3. 配置Spring Security,将AOP切面类添加到Spring Security的配置中。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private TokenValidationAspect tokenValidationAspect; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // 配置需要Token验证的接口 .anyRequest().authenticated() .and() .csrf().disable(); // 将AOP切面类添加到Spring Security的配置中 http.addFilterBefore(tokenValidationAspect, UsernamePasswordAuthenticationFilter.class); } } ``` 4. 在需要不需要Token验证的接口上,添加`@NoTokenRequired`注解。 ```java @RestController public class ExampleController { @NoTokenRequired @GetMapping("/example") public String example() { return "This API does not require Token"; } } ``` 这样配置之后,带有`@NoTokenRequired`注解的接口将不会进行Spring Security的Token验证,即可在没有Token的情况下访问该接口。其他接口仍然需要进行Token验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值