Java注解初识

Java注解初识,第1张

Java注解初识 前言

注解基础知识及使用示例
博客地址:芒果橙的个人博客 【http://mangocheng.com】

含义:可以理解为标签,用以提示和赋予类或属性信息

一、基础 1. 元注解

注解的注解,表明注解的信息

  • @Target:规定注解可以用在哪里
    • 取值:ElementType
      • TYPE:类和接口
      • FIELD:字段、枚举
      • METHOD
      • PARAMETER
      • CONSTRUCTOR:构造
      • LOCAL_VARIBLE:局部变量
      • ANNOTATION_TYPE:注解
      • PACKAGE:包
  • @Retention:规定注解可以存在于哪里
    • 取值:RetentionPolicy
      • SOURCE:源代码
      • CLASS:源代码、编译后的字节文件
      • RUNTIME:源代码中、 编译以后的字节码文件中、 运行时内存中, 程序可以通过反射获取该注解
  • document:说明该注解将被包含在javadoc中
  • Inherited:说明子类可以继承父类中的该注解
2.预置注解
  • Deprecated:标识过时
  • SuppressWarnings:忽略警告
二、使用 1.通过反射获取注解信息
  • 对于属性字段注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{

private String name;
private String value;
}
// field也是通过反射获取的
MyAnnotation ma = field.getAnnotation(MyAnnotation.class);
  • Spring自定义接口参数校验注解 参考

示例:控制层接口方法参数校验

场景,提供的外部接口需校验传递参数的非空性

  1. 自定义注解

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyNotNull {
    
        
        boolean empty() default false;
    }
    
  2. 控制层切面

    @Component
    @Aspect
    public class MyControllerAspect {
    
        
      private final String executeExpr = "execution(* com.mango.xx.web..*Controller.*(..))";
    
    
        
    @Around(executeExpr)
    public Object processLog(ProceedingJoinPoint proceedingJoinPoint) throws IllegalAccessException {
        // 方法
        // Method method = ((MethodSignature)proceedingJoinPoint.getSignature()).getMethod();
    //        Class rc = method.getReturnType();
            // 参数
            Object[] args = proceedingJoinPoint.getArgs();
            // 参数校验
            for (Object arg : args) {
                // 参数校验
                String msg = processArg(arg);
                if(!StringUtils.isEmpty(msg)){
                    ResultMessage resultMessage = new ResultMessage();
                    resultMessage.setSuccess(false);
                    resultMessage.setCode(-1);
                    resultMessage.setMsg(new StringBuilder(msg));
                    return resultMessage;
                }
                
            }
            // 方法名称
    //        String methodName = method.getName();
    
            Object res = null;
            try {
                // 继续执行方法
                res = proceedingJoinPoint.proceed(args);
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
    
            return res;
    
        }
    
        
        private String processArg(Object arg) throws IllegalAccessException {
            Field[] fields = arg.getClass().getDeclaredFields();
            StringBuilder msg = new StringBuilder();
            for (Field field : fields) {
                if(field.isAnnotationPresent(MyNotNull.class)){
                    field.setAccessible(true);
                    MyNotNull annotation = field.getAnnotation(MyNotNull.class);
                    boolean empty = annotation.empty();
                    Object value = field.get(arg);
                    Class fieldType = field.getType();
                    if(fieldType == String.class){
                        if(!empty){
                            if(StringUtils.isEmpty(value)){
                                msg.append(field.getName() + " 不能为空");
                                msg.append(";");
                            }
                        }
                    }
                }
            }
            return msg.toString();
        }
    }
    
  3. 使用注解

    // 控制层方法
    @PostMapping(value = "/loadLove")
    public Result loadLove(@RequestBody heartVO){
        
        // ...
        return xx.loadLove(heartVO);
    }
    
    // 请求参数实体
    public class heartVO {
        
        @MyNotNull
        private String truth;
        
        @MyNotNull
        private String heart;
        
        // ...
    }
    
三、前置知识-AOP 1、基础

1.含义:Aspect Oriented Programming编程范式,程序设计思想

2.目的:把通用逻辑从业务逻辑分离出来

3.常用术语

  • Join point:拦截点,如某个业务方法
  • Pointcut:Joinpoint的表达式,表示拦截哪些方法;一个P对应多个J
  • Advice:要切入的逻辑,增强处理
    • BeforeAdvice:在方法前切入
    • AfterAdvice:在方法后切入
    • AfterReturningAdvice:在方法返回后切入,抛出异常则不会切入
    • AfterThrowingAdvice:在方法抛出异常时插入
    • AroundAdvice:在方法执行前后切入,可以中断或忽略原有流程的执行
  • Target Object:目标对象,被一个或多个切面通知的对象
  • Weaving:织入,将切面应用到目标对象的过程

4.切面代码织入时机

  • 编译期
  • 类加载期
  • 运行期

5.实现类别

  • 静态AOP实现:AOP框架再编译阶段对程序进行修改,生成静态的AOP代理类。以AspectJ为代表
  • 动态AOP实现:AOP框架在运行阶段动态生成AOP代理(实现对目标类的增强)。以Spring AOP为代表:jdk动态代理(实现接口)、cglib(继承)

6.实现内容

  • 定义普通业务组件
  • 定义切入点,一个切入点可以横切多个业务组件
  • 定义增强处理,增强处理就是在AOP框架为普通业务组织织入的处理动作

参考:https://www.jianshu.com/p/9aed3fb454df

2、Spring AOP

Spring中的AOP代理和其依赖关系由Spring的IOC容器负责生成、管理

1.定义切入点和增强处理的方式

  • 基于注解的“零配置”方式:使用@Aspect、@Pointcut等注解
  • 基于XML配置文件:Spring配置文件

2.注解方式

  • @Aspect – 作用是把当前类标识为一个切面供容器读取
  • @Pointcut – (切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达
  • @Before – 标识一个前置增强方法,相当于BeforeAdvice的功能
  • @AfterReturning – 后置增强,相当于AfterReturningAdvice,方法退出时执行
  • @AfterThrowing – 异常抛出增强,相当于ThrowsAdvice
  • @After – final增强,不管是抛出异常或者正常退出都会执行
  • @Around – 环绕增强,相当于MethodInterceptor

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5661213.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存