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;
疑问
我定义了注解,为啥注解到类上不起作用是哪里错了?求指点。
相关文章
|
4月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
327 26
|
5月前
|
缓存 Java 数据库
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
263 89
|
3月前
|
JSON 前端开发 Java
Spring MVC常用的注解
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中 的所有响应请求的方法都是以该地址作为父路径。 @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。 @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。 @Controller:控制器的注解,表示是表现层,不能用用别的注解代替 @RestController : 组合注解 @Conntroller + @ResponseBody @GetMapping , @PostMapping , @Put
|
3月前
|
Java Spring
Spring Boot的核心注解是哪个?他由哪几个注解组成的?
Spring Boot的核心注解是@SpringBootApplication , 他由几个注解组成 : ● @SpringBootConfiguration: 组合了- @Configuration注解,实现配置文件的功能; ● @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项 ● @ComponentScan:Spring组件扫描
|
3月前
|
Java 测试技术 Spring
SpringBoot+@Async注解一起用,速度提升
本文介绍了异步调用在高并发Web应用性能优化中的重要性,对比了同步与异步调用的区别。同步调用按顺序执行,每一步需等待上一步完成;而异步调用无需等待,可提升效率。通过Spring Boot示例,使用@Async注解实现异步任务,并借助Future对象处理异步回调,有效减少程序运行时间。
|
6月前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
248 73
|
2月前
|
人工智能 缓存 自然语言处理
保姆级Spring AI 注解式开发教程,你肯定想不到还能这么玩!
这是一份详尽的 Spring AI 注解式开发教程,涵盖从环境配置到高级功能的全流程。Spring AI 是 Spring 框架中的一个模块,支持 NLP、CV 等 AI 任务。通过注解(如自定义 `@AiPrompt`)与 AOP 切面技术,简化了 AI 服务集成,实现业务逻辑与 AI 基础设施解耦。教程包含创建项目、配置文件、流式响应处理、缓存优化及多任务并行执行等内容,助你快速构建高效、可维护的 AI 应用。
|
4月前
|
Java Maven 开发者
编写SpringBoot的自定义starter包
通过本文的介绍,我们详细讲解了如何创建一个Spring Boot自定义Starter包,包括自动配置类、配置属性类、`spring.factories`文件的创建和配置。通过自定义Starter,可以有效地复用公共配置和组件,提高开发效率。希望本文能帮助您更好地理解和应用Spring Boot自定义Starter,在实际项目中灵活使用这一强大的功能。
142 17
|
4月前
|
监控 Java Spring
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
121 16
|
3月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
74 0