java自定义注解为空值_java 自定义注解
转载自(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 自定义注解相关推荐
- java自定义注解为空值_java自定义注解
1. Java注解(Annotation) Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 注解相关类都包含在java.lang.annot ...
- java注解获取参数_JAVA 自定义注解及参数获取 | 学步园
package com.java.annotation; import java.lang.annotation.*; /** * Created by lw on 14-5-30. * 自定义注解 ...
- Java通过自定义注解执行方法_Java自定义注解(使用篇)
TL;DR Java 注解广泛运用在开发之中,用于增强变量/方法/类等. 尝试说明 Java 自定义注解的使用,以及通过开源项目中的使用进行说明. 本文主要记录个人的理解,全文基于Java SE8. ...
- java注解定义常量_java自定义注解
1.Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型.该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的c ...
- java中注解的使用_java中注解的使用
使用过ssh框架的人一定也使用过注解,尤其是在spring框架中,注解可谓是spring容器和AOP编程的重要环节.注解就是用于修饰类.全局变量.方法.参数或局部变量的接口,java中规定,注解的使用 ...
- java 注解数组初始化_Java 之 注解的定义
一.元注解 1.元注解概述 元注解:用于描述注解的注解 2.常用的元注解 (1)@Target:描述注解能够作用的位置 Target 里面是一个 ElementType[] value() 的枚举数组 ...
- @data注解的作用_Java中注解学习系列教程-2
在上一篇文章中,我们讲解了:Java中注解的定义.JDK中内置注解.第三方注解. 本文是注解系列教程中的第二篇.来看看今天主要内容: 1:注解的分类 2:元注解说明 3:自定义注解声明 一:注解的 ...
- java中list去除空值_Java –从列表中删除所有空值
java中list去除空值 介绍: 在本文中,我们将学习如何使用普通的Java,Java 8 lambda表达式和某些第三方库从Java 列表中删除空值 . 所以,让我们开始吧! 从Java中的 让我 ...
- java自定义封装一个方法_Java自定义套件封装教程
Java自定义套件封装教程 时间:2017-07-28 来源:华清远见JAVA学院 各位亲爱的小伙伴们大家好,近很多伙伴都问我该怎么做Java自定义套件封装,今天华清Java学院小编在这里做了 ...
最新文章
- Python——Entry、Text控件
- SAP 同一个序列号可以同时出现在2个不同的HU里?
- (四)工况曲线构建 2019年研究生数学建模D题《汽车行驶工况构建》
- python精通书籍-清华学霸整理,Python入门到精通这几本书帮你快速入行
- Windows Phone开发(18):变形金刚第九季——变换
- mina 粘包、多包和少包的解决方法
- 学习 ASP.NET MVC (第五回)理论篇
- Phycharm下载并安装
- js读取本地excel到html,JS读取本地EXCEL文件
- 转载:如何用手机复制门禁卡
- mac pdf去水印_Acrobat XI PRO/DC 2019 PDF编辑转换器去水印 WIN/MAC
- 用计算机软件绘制思维导图,一款简单好用的在线免费思维导图制作工具
- 电子通讯录(数据库版存储)
- 代码自动删除QQ空间里的说说
- 密码学之前后向安全性
- 十条网站盈利模式分析总结
- 报错:Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.
- 语音合成模型小抄(1)
- 校园网服务器系统方案设计,校园网服务器系统项目设计方案.pdf
- 计蒜客 428(人人都有极客精神-日期问题)
热门文章
- win10 qq远程不上服务器未响应,Win10系统QQ远程协助时无法使用鼠标点击的解决方法...
- ProGuard简介
- sdl 游戏引擎c语言,kys-cpp: 《金庸群侠传》C++复刻版,这是一个以SDL2为基础实现的2D游戏引擎。同时相当于提供了一个使用该引擎制作DOS游戏《金庸群侠传》移植版的范例。...
- 使用Python进行Grad-CAM ++:深度卷积网络的改进视觉解释
- 以太坊的革命理想和商业现实
- 技嘉计算机主板排行,2019人气电脑主板排名前十 买个好主板相当于给电脑买个好身体...
- 在jupyter notebook获取当前环境的所有库的列表
- 全志H8/a83t专业安卓KTV主板,支持双屏异显,接口丰富,支持vga、hdmi、cvbs显示
- java 下拉列表加日期,javascript 下拉框显示当前日期
- 无盘服务器网卡参数怎么设置,无盘 网卡属性设置(详细)(Diskless network card property settings (details)).doc...