元编程及实践

元编程及实践

Java annotation

From Wikipedia, the free encyclopedia

Jump to navigation

Jump to search

In the Java computer programming language, an annotation is a form of syntactic metadata that can be added to Java source code.[1] Classes, methods, variables, parameters and packages may be annotated. Like Javadoc tags, Java annotations can be read from source files. Unlike Javadoc tags, Java annotations can also be embedded in and read from class files generated by the compiler. This allows annotations to be retained by Java VM at run-time and read via reflection.[2] It is possible to create meta-annotations out of the existing ones in Java.我们

经常在使用的注解编程,也叫元编程。在wiki中已经有定义。

•注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁。

•Java SE 5.0 版本中开始引入的概念

•与和interface一样是一种类型

public @interface Person {
String name() default "";
}

•什么是元注解

–标注在注解上的注解

元注解

•@ Retention :注解存活时间

–RetentionPolicy

•SOURCE

•CLASS

•RUNTIME

•@ Target:运用的目标地方

–ElementType

•TYPE,

•FIELD,

•METHOD,

•PARAMETER,

•CONSTRUCTOR,

•LOCAL_VARIABLE,

•ANNOTATION_TYPE,

•PACKAGE,

•TYPE_PARAMETER,

•TYPE_USE

•@ Documented

•@ Inherited :被注解的注解的类的子类,也会存在被注解的注解

•@ Repeatable

–1.8

Java标准注解

@Deprecated

–1.5

@Override

–1.5

@SuppressWarnings

–1.5

•@SafeVarargs

–1.7

@FunctionalInterface

–1.8

注解属性

•注解只有成员变量,没有方法。

• 属性类型必须是基本类型、枚举和数组

如上面自定义注解的

String name() default "";

注解提取

•判断是否属于某个注解

–isAnnotationPresent

•获取注解对象

–getAnnotation

•获取所有注解

–getAnnotations

自定义注解

@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Person {
String name() default "";
}

这个注解应用于方法、字段

应用于项目中的实践

•返回对象中必须存在店铺编码字段,并赋值

•查询商品信息,需要有商品编码字段,并赋值

•不需要寻最优分销商,则需要分销商字段,并赋值

/**
* 自动设置返回对象属性值

*
* @since 1226版本
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoSetterAttribute {
/**
* 是否需要最优分销商
*
* @return
*/
boolean optimalDistributor() default false;
}

•在需要获取商品或店铺信息的方法,添加@AutoSetterAttribute

•若接口无分销商,则需要寻最优分销商,使用optimalDistributor=true

在应用的方法中如下

第一步,在使用的方法中注入切面

@AutoSetterAttribute
public PaginationVO<list>> getSaleRefundCheckList(String storeCode, String buyerPhone, Integer pageNum, Integer pageSize)
throws BusinessException {
...
}
/<list>

第二步在返回字段的VO中加入注解

public class RefundCheckListVO {
@Store(code = true)
private String storeCode;
/**
* 商品编码
*/
@Goods(code = true)
private String cmmdtyCode;

/**
* 商品名称
*/
@Goods(name = true)
private String cmmdtyName;

/**
* 商品图片地址
*/
@Goods(image = true)
private String imageUrl;

...
}

通过反射获取VO字段,然后进行赋值,

Class> objectClass = object.getClass();
Field[] fields = objectClass.getDeclaredFields();
List<field> goodsFieldList = Lists.newArrayList();
List<field> storeFieldList = Lists.newArrayList();
for (Field field : fields) {
//属性是列表
if (field.getType().isAssignableFrom(List.class)) {
findField(getMethodValue(object, field));
}
//属性是订单行
if (null != field.getAnnotation(OrderLine.class)) {
findField(getMethodValue(object, field));
}
//无 Annotation
Annotation[] annotations = field.getAnnotations();
if (annotations.length == 0) {
continue;
}
Store annotation = field.getAnnotation(Store.class);
if (null != annotation) {
storeFieldList.add(field);
continue;
}
Goods goodsAnnotation = field.getAnnotation(Goods.class);
if (null != goodsAnnotation) {
goodsFieldList.add(field);
continue;
}
}

/<field>/<field>

获取到字段后,对字段进行赋值

private void setField(Object object, Field field, Object fieldValue) throws BusinessException {
if (null == field) {
return;
}
field.setAccessible(true);
try {
field.set(object, fieldValue);
} catch (IllegalAccessException e) {
logger.error("字段赋值异常 field={}", field.getName(), e);
throw new BusinessException("字段赋值异常");
}
}

因VO对象的属性字段都是private的,所以要对属性使用field.setAccessible(true)

以上是这次实践的整理思路。

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

若有需要请加入微信公众号“零售云技术”


分享到:


相關文章: