转载自(https://www.cnblogs.com/liangweiping/p/3837332.html)

目录

1.通过自定义注解,进行赋值

2.通过自定义注解,进行校验

3.实际应用如何应用自定义注解

4.其他注意事项

-----------------------------

1.通过自定义注解,进行赋值

1.自定义注解

package annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* Init.java

*

* @author IT唐伯虎 2014年7月10日

*/

@Documented

@Inherited

@Target({ ElementType.FIELD, ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

public @interface Init

{

public String value() default "";

}

2.在数据模型使用注解

package model;

import annotation.Init;

/**

* User.java

*

* @author IT唐伯虎 2014年7月10日

*/

public class User

{

private String name;

private String age;

public String getName()

{

return name;

}

@Init(value = "liang")

public void setName(String name)

{

this.name = name;

}

public String getAge()

{

return age;

}

@Init(value = "23")

public void setAge(String age)

{

this.age = age;

}

}

3.用“构造工厂”充当“注解解析器”

package factory;

import java.lang.reflect.Method;

import annotation.Init;

import model.User;

/**

* UserFactory.java

*

* @author IT唐伯虎 2014年7月10日

*/

public class UserFactory

{

public static User create()

{

User user = new User();

// 获取User类中所有的方法(getDeclaredMethods也行)

Method[] methods = User.class.getMethods();

try

{

for (Method method : methods)

{

// 如果此方法有注解,就把注解里面的数据赋值到user对象

if (method.isAnnotationPresent(Init.class))

{

Init init = method.getAnnotation(Init.class);

method.invoke(user, init.value());

}

}

}

catch (Exception e)

{

e.printStackTrace();

return null;

}

return user;

}

}

4.运行的代码

package app;

import java.lang.reflect.InvocationTargetException;

import factory.UserFactory;

import model.User;

/**

* Test.java

*

* @author IT唐伯虎 2014年7月10日

*/

public class Test

{

public static void main(String[] args) throws IllegalAccessException,

IllegalArgumentException, InvocationTargetException

{

User user = UserFactory.create();

System.out.println(user.getName());

System.out.println(user.getAge());

}

}

5.运行结果

liang

23

2.通过自定义注解,进行校验

1.自定义注解

package annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* Validate.java

*

* @author IT唐伯虎 2014年7月11日

*/

@Documented

@Inherited

@Target({ ElementType.FIELD, ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

public @interface Validate

{

public int min() default 1;

public int max() default 10;

public boolean isNotNull() default true;

}

2.在数据模型使用注解

package model;

import annotation.Validate;

/**

* User.java

*

* @author IT唐伯虎 2014年7月11日

*/

public class User

{

@Validate(min = 2, max = 5)

private String name;

@Validate(isNotNull = false)

private String age;

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

public String getAge()

{

return age;

}

public void setAge(String age)

{

this.age = age;

}

}

3.注解解析器

package check;

import java.lang.reflect.Field;

import annotation.Validate;

import model.User;

/**

* UserCheck.java

*

* @author IT唐伯虎 2014年7月11日

*/

public class UserCheck

{

public static boolean check(User user)

{

if (user == null)

{

System.out.println("!!校验对象为空!!");

return false;

}

// 获取User类的所有属性(如果使用getFields,就无法获取到private的属性)

Field[] fields = User.class.getDeclaredFields();

for (Field field : fields)

{

// 如果属性有注解,就进行校验

if (field.isAnnotationPresent(Validate.class))

{

Validate validate = field.getAnnotation(Validate.class);

if (field.getName().equals("age"))

{

if (user.getAge() == null)

{

if (validate.isNotNull())

{

System.out.println("!!年龄可空校验不通过:不可为空!!");

return false;

}

else

{

System.out.println("年龄可空校验通过:可以为空");

continue;

}

}

else

{

System.out.println("年龄可空校验通过");

}

if (user.getAge().length() < validate.min())

{

System.out.println("!!年龄最小长度校验不通过!!");

return false;

}

else

{

System.out.println("年龄最小长度校验通过");

}

if (user.getAge().length() > validate.max())

{

System.out.println("!!年龄最大长度校验不通过!!");

return false;

}

else

{

System.out.println("年龄最大长度校验通过");

}

}

if (field.getName().equals("name"))

{

if (user.getName() == null)

{

if (validate.isNotNull())

{

System.out.println("!!名字可空校验不通过:不可为空!!");

return false;

}

else

{

System.out.println("名字可空校验通过:可以为空");

continue;

}

}

else

{

System.out.println("名字可空校验通过");

}

if (user.getName().length() < validate.min())

{

System.out.println("!!名字最小长度校验不通过!!");

return false;

}

else

{

System.out.println("名字最小长度校验通过");

}

if (user.getName().length() > validate.max())

{

System.out.println("!!名字最大长度校验不通过!!");

return false;

}

else

{

System.out.println("名字最大长度校验通过");

}

}

}

}

return true;

}

}

4.运行的代码

package app;

import check.UserCheck;

import model.User;

/**

* Test.java

*

* @author IT唐伯虎 2014年7月11日

*/

public class Test

{

public static void main(String[] args)

{

User user = new User();

user.setName("liang");

user.setAge("1");

System.out.println(UserCheck.check(user));

}

}

5.运行结果

名字可空校验通过

名字最小长度校验通过

名字最大长度校验通过

年龄可空校验通过

年龄最小长度校验通过

年龄最大长度校验通过

true

3.实际应用如何应用自定义注解

Q: 实际我们用的时候,比如校验,加上注解之后,我们给user对象set值,会自动校验,不会主动调用check方法,这部分是怎么个实现原理,楼主能否补充一下,谢谢?

A:实际项目中通过拦截器或者切面来实现:

1、定义一个interface,命名为BaseCheck,BaseCheck里面有一个抽象的check方法,check方法返回值是boolean。

2、定义校验的注解,比如:@NotNull、@Length。

3、根据上面的注解,分别定义对应的校验类,比如:NotNullCheck、LengthCheck。

4、NotNullCheck、LengthCheck都需要实现BaseCheck的check方法,你要在check方法里面写校验流程。

5、定义一个容器,在工程启动的时候,把NotNullCheck和LengthCheck的对象塞到里面,

如果你使用spring,直接在NotNullCheck和LengthCheck上面加个注解@Component,也能达到同样的效果。

6、定义一个拦截器或者切面。

7、在这个拦截器或者切面里,拿到请求的参数,也就是那个user对象。

8、通过反射,获取到这个user对象所对应的类,类的名字肯定就是User了。

9、遍历User里面的所有Field,检查每一个Field是否含有注解。

10、遍历Field上的所有注解。

11、假设找到一个注解@NotNull,就去找一下对应的校验类,

BaseCheck baseCheck = 容器.get("NotNullCheck")

或者BaseCheck baseCheck = (BaseCheck) SpringUtl.getBean("NotNullCheck")

12、如果找到,也就是baseCheck不为空,则通过反射获取这个Field的实际值,将这个值作为参数,调用baseCheck.check方法

13、baseCheck.check如果返回false则报错,如果返回true则继续,直到遍历完所有Field、所有注解

4.其他注意事项

1-如下定义,是spring中定义@Service注解,

意味着@Service 继承了 @Component注解的所有功能

java自定义注解为空值_java 自定义注解相关推荐

  1. java自定义注解为空值_java自定义注解

    1. Java注解(Annotation) Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 注解相关类都包含在java.lang.annot ...

  2. java注解获取参数_JAVA 自定义注解及参数获取 | 学步园

    package com.java.annotation; import java.lang.annotation.*; /** * Created by lw on 14-5-30. * 自定义注解 ...

  3. Java通过自定义注解执行方法_Java自定义注解(使用篇)

    TL;DR Java 注解广泛运用在开发之中,用于增强变量/方法/类等. 尝试说明 Java 自定义注解的使用,以及通过开源项目中的使用进行说明. 本文主要记录个人的理解,全文基于Java SE8. ...

  4. java注解定义常量_java自定义注解

    1.Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型.该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的c ...

  5. java中注解的使用_java中注解的使用

    使用过ssh框架的人一定也使用过注解,尤其是在spring框架中,注解可谓是spring容器和AOP编程的重要环节.注解就是用于修饰类.全局变量.方法.参数或局部变量的接口,java中规定,注解的使用 ...

  6. java 注解数组初始化_Java 之 注解的定义

    一.元注解 1.元注解概述 元注解:用于描述注解的注解 2.常用的元注解 (1)@Target:描述注解能够作用的位置 Target 里面是一个 ElementType[] value() 的枚举数组 ...

  7. @data注解的作用_Java中注解学习系列教程-2

    在上一篇文章中,我们讲解了:Java中注解的定义.JDK中内置注解.第三方注解. 本文是注解系列教程中的第二篇.来看看今天主要内容: ​ 1:注解的分类 2:元注解说明 3:自定义注解声明 一:注解的 ...

  8. java中list去除空值_Java –从列表中删除所有空值

    java中list去除空值 介绍: 在本文中,我们将学习如何使用普通的Java,Java 8 lambda表达式和某些第三方库从Java 列表中删除空值 . 所以,让我们开始吧! 从Java中的 让我 ...

  9. java自定义封装一个方法_Java自定义套件封装教程

    Java自定义套件封装教程 时间:2017-07-28     来源:华清远见JAVA学院 各位亲爱的小伙伴们大家好,近很多伙伴都问我该怎么做Java自定义套件封装,今天华清Java学院小编在这里做了 ...

最新文章

  1. Python——Entry、Text控件
  2. SAP 同一个序列号可以同时出现在2个不同的HU里?
  3. (四)工况曲线构建 2019年研究生数学建模D题《汽车行驶工况构建》
  4. python精通书籍-清华学霸整理,Python入门到精通这几本书帮你快速入行
  5. Windows Phone开发(18):变形金刚第九季——变换
  6. mina 粘包、多包和少包的解决方法
  7. 学习 ASP.NET MVC (第五回)理论篇
  8. Phycharm下载并安装
  9. js读取本地excel到html,JS读取本地EXCEL文件
  10. 转载:如何用手机复制门禁卡
  11. mac pdf去水印_Acrobat XI PRO/DC 2019 PDF编辑转换器去水印 WIN/MAC
  12. 用计算机软件绘制思维导图,一款简单好用的在线免费思维导图制作工具
  13. 电子通讯录(数据库版存储)
  14. 代码自动删除QQ空间里的说说
  15. 密码学之前后向安全性
  16. 十条网站盈利模式分析总结
  17. 报错:Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.
  18. 语音合成模型小抄(1)
  19. 校园网服务器系统方案设计,校园网服务器系统项目设计方案.pdf
  20. 计蒜客 428(人人都有极客精神-日期问题)

热门文章

  1. win10 qq远程不上服务器未响应,Win10系统QQ远程协助时无法使用鼠标点击的解决方法...
  2. ProGuard简介
  3. sdl 游戏引擎c语言,kys-cpp: 《金庸群侠传》C++复刻版,这是一个以SDL2为基础实现的2D游戏引擎。同时相当于提供了一个使用该引擎制作DOS游戏《金庸群侠传》移植版的范例。...
  4. 使用Python进行Grad-CAM ++:深度卷积网络的改进视觉解释
  5. 以太坊的革命理想和商业现实
  6. 技嘉计算机主板排行,2019人气电脑主板排名前十 买个好主板相当于给电脑买个好身体...
  7. 在jupyter notebook获取当前环境的所有库的列表
  8. 全志H8/a83t专业安卓KTV主板,支持双屏异显,接口丰富,支持vga、hdmi、cvbs显示
  9. java 下拉列表加日期,javascript 下拉框显示当前日期
  10. 无盘服务器网卡参数怎么设置,无盘 网卡属性设置(详细)(Diskless network card property settings (details)).doc...