springboot-自定义注解拦截ip aop和ioc

简介: springboot-自定义注解拦截ip aop和ioc
定义LimitIp
package com.blove.ityustudy.annotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LimitIp {
    String ip() default "";
}

定义IpAspect
package com.blove.ityustudy.aop;


import com.blove.ityustudy.annotation.LimitIp;
import com.blove.util.IPUtils;
import com.blove.util.RUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


@Aspect
@Component
@Slf4j
public class IpAspect {

    @Pointcut("@annotation(com.blove.ityustudy.annotation.LimitIp)")
    public void annotationPointcut() {

    }

    @Before("annotationPointcut()")
    public void beforePointcut(JoinPoint joinPoint) {
        log.info("beforePointcut");
    }

    @After("annotationPointcut()")
    public void afterPointcut(JoinPoint joinPoint) {
        log.info("afterPointcut");
    }

    /**
     * 拦截器具体实现
     * @param pjp
     * @return JsonResult(被拦截方法的执行结果,或需要登录的错误提示。)
     */
    @Around("annotationPointcut()") //指定拦截器规则;也可以直接把“execution(* com.xjj.........)”写进这里
    public Object Interceptor(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod(); //获取被拦截的方法
        String methodName = method.getName(); //获取被拦截的方法名
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();

        LimitIp annotation = method.getAnnotation(LimitIp.class);
        String value = annotation.ip();
        String ip = IPUtils.getRealIP(request);
        if(value.equals(ip)){
            try {
                return pjp.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                return RUtil.error(throwable.getMessage());
            }
        }else{
            return RUtil.error("调用失败");
        }
    }

}

使用
 @ApiOperation(value = "获取用户信息")
    @ApiImplicitParams({ // 参数说明
            @ApiImplicitParam(name = "name", paramType = "query", value = "用户名字", dataType = "string", required = true),
            @ApiImplicitParam(name = "sex", paramType = "query", value = "性别", dataType = "Integer"),
            @ApiImplicitParam(name = "city", paramType = "query", value = "城市", dataType = "string"),
    })
    @PostMapping(value = "/getUser")
    @LimitIp(ip = "127.0.0.1")
    public R<UserModel> getUser(@RequestParam(value = "name") String name, @RequestParam(value = "sex", required = false) Integer sex, @RequestParam(value = "city", required = false) String city) {
        if (!StringUtils.isBlank(city)) {
            return RUtil.ok(new UserModel().setName(name).setAge(sex).setCity(city));
        }
        throw new CommonException("城市不能为空");
    }
学习
1. @Target 这个注解可以放到那个位置,例如类上,方法上,属性上等
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE,

    /**
     * Module declaration.
     *
     * @since 9
     */
    MODULE
}
2. @Retention
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
3. @Documented
AOP
满足 pointcut 规则的 joinpoint 会被添加相应的 advice 操作.
方法的生命周期:1,调用前,调用中,调用后(不关注结果),调用成功(调用返回异常),

Before-> After-> Around-> AfterReturning(AfterThrowing)

知道了生命周期就可以在任何地方切入了。


IOC

早期: 你需要啥,new一个就行了

ioc: 你需要啥,你先通过注解的方式告诉容器,让容器给你创建出来,当你需要的地方直接导入就行了

标注需求(@Component)
//读取classpath配置信息
@Data
@Component
@PropertySource(value = {"classpath:config.yml"},encoding = "utf-8")
public class FileConfig {
    @Value("${staticAccessPath}")
    private String staticAccessPath;
    @Value("${uploadFolder}")
    private String uploadFolder;
    @Value("${min}")
    private int min;
    @Value("${max}")
    private int max;

    @Override
    public String toString() {
        return "FileConfig{" +
                "staticAccessPath='" + staticAccessPath + '\'' +
                ", uploadFolder='" + uploadFolder + '\'' +
                ", min='" + min + '\'' +
                ", max='" + max + '\'' +
                '}';
    }
}
导入需求( @Autowired)
@Autowired
    FileConfig fileConfig;
疑问
我定义了注解,为啥注解到类上不起作用是哪里错了?求指点。
相关文章
|
9天前
|
Java Spring 容器
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
|
8天前
|
前端开发 Java Spring
蓝易云 - 详解SpringBoot的常用注解
以上就是SpringBoot中常用的一些注解,正确理解和使用这些注解,可以帮助我们更好地使用SpringBoot框架进行开发。
11 0
|
9天前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
10 0
|
9天前
|
Java 机器人 测试技术
Spring Boot中的自定义注解应用
Spring Boot中的自定义注解应用
|
23天前
|
Java Maven 数据安全/隐私保护
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
27 1
|
10天前
|
前端开发 Java 数据库
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
|
10天前
|
XML Java 数据格式
技术好文:Spring基础篇——AOP切面编程
技术好文:Spring基础篇——AOP切面编程
|
2月前
|
XML 监控 安全
Spring特性之一——AOP面向切面编程
Spring特性之一——AOP面向切面编程
42 1
|
5天前
|
XML 监控 Java
Java中的AOP编程:AspectJ与Spring AOP的应用
Java中的AOP编程:AspectJ与Spring AOP的应用
|
24天前
|
XML Java 程序员
Java一分钟之-AOP:面向切面编程
【6月更文挑战第13天】Java中的AOP允许程序员定义切面,将日志、事务等通用功能与业务逻辑解耦。切面包括通知(Advice,如前置、后置等)和切入点(Pointcut,定义执行点)。Spring框架通过代理和@AspectJ注解支持AOP。常见问题包括代理对象理解错误、切入点表达式错误、环绕通知处理不当和配置遗漏。理解和实践中,AOP能提升代码可维护性和可扩展性。
39 5