Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ma yanling
hutool-5-master
Commits
45cda665
Commit
45cda665
authored
Sep 25, 2024
by
ma yanling
Browse files
project commit
parent
ad2fb30a
Pipeline
#2354
failed with stages
in 0 seconds
Changes
369
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2051 additions
and
0 deletions
+2051
-0
hutool-core/src/main/java/cn/hutool/core/annotation/ForceAliasFor.java
...rc/main/java/cn/hutool/core/annotation/ForceAliasFor.java
+35
-0
hutool-core/src/main/java/cn/hutool/core/annotation/ForceAliasedAnnotationAttribute.java
...tool/core/annotation/ForceAliasedAnnotationAttribute.java
+49
-0
hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAggregateAnnotation.java
...ore/annotation/GenericSynthesizedAggregateAnnotation.java
+318
-0
hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java
.../hutool/core/annotation/GenericSynthesizedAnnotation.java
+197
-0
hutool-core/src/main/java/cn/hutool/core/annotation/Hierarchical.java
...src/main/java/cn/hutool/core/annotation/Hierarchical.java
+155
-0
hutool-core/src/main/java/cn/hutool/core/annotation/Link.java
...ol-core/src/main/java/cn/hutool/core/annotation/Link.java
+49
-0
hutool-core/src/main/java/cn/hutool/core/annotation/MirrorFor.java
...re/src/main/java/cn/hutool/core/annotation/MirrorFor.java
+42
-0
hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java
...ol/core/annotation/MirrorLinkAnnotationPostProcessor.java
+132
-0
hutool-core/src/main/java/cn/hutool/core/annotation/MirroredAnnotationAttribute.java
...n/hutool/core/annotation/MirroredAnnotationAttribute.java
+48
-0
hutool-core/src/main/java/cn/hutool/core/annotation/PropIgnore.java
...e/src/main/java/cn/hutool/core/annotation/PropIgnore.java
+21
-0
hutool-core/src/main/java/cn/hutool/core/annotation/RelationType.java
...src/main/java/cn/hutool/core/annotation/RelationType.java
+50
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java
...utool/core/annotation/SynthesizedAggregateAnnotation.java
+102
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java
...java/cn/hutool/core/annotation/SynthesizedAnnotation.java
+96
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationAttributeProcessor.java
...e/annotation/SynthesizedAnnotationAttributeProcessor.java
+24
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java
...l/core/annotation/SynthesizedAnnotationPostProcessor.java
+71
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationProxy.java
...cn/hutool/core/annotation/SynthesizedAnnotationProxy.java
+160
-0
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationSelector.java
...hutool/core/annotation/SynthesizedAnnotationSelector.java
+82
-0
hutool-core/src/main/java/cn/hutool/core/annotation/WrappedAnnotationAttribute.java
...cn/hutool/core/annotation/WrappedAnnotationAttribute.java
+125
-0
hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java
...src/main/java/cn/hutool/core/annotation/package-info.java
+7
-0
hutool-core/src/main/java/cn/hutool/core/annotation/scanner/AbstractTypeAnnotationScanner.java
...ore/annotation/scanner/AbstractTypeAnnotationScanner.java
+288
-0
No files found.
Too many changes to show.
To preserve performance only
369 of 369+
files are displayed.
Plain diff
Email patch
hutool-core/src/main/java/cn/hutool/core/annotation/ForceAliasFor.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.*
;
/**
* <p>{@link Link}的子注解。表示“原始属性”将强制作为“关联属性”的别名。效果等同于在“原始属性”上添加{@link Alias}注解,
* 任何情况下,获取“关联属性”的值都将直接返回“原始属性”的值
* <b>注意,该注解与{@link Link}、{@link AliasFor}或{@link MirrorFor}一起使用时,将只有被声明在最上面的注解会生效</b>
*
* @author huangchengxing
* @see Link
* @see RelationType#FORCE_ALIAS_FOR
*/
@Link
(
type
=
RelationType
.
FORCE_ALIAS_FOR
)
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
public
@interface
ForceAliasFor
{
/**
* 产生关联的注解类型,当不指定时,默认指注释的属性所在的类
*
* @return 关联注解类型
*/
@Link
(
annotation
=
Link
.
class
,
attribute
=
"annotation"
,
type
=
RelationType
.
FORCE_ALIAS_FOR
)
Class
<?
extends
Annotation
>
annotation
()
default
Annotation
.
class
;
/**
* {@link #annotation()}指定注解中关联的属性
*
* @return 关联的属性
*/
@Link
(
annotation
=
Link
.
class
,
attribute
=
"attribute"
,
type
=
RelationType
.
FORCE_ALIAS_FOR
)
String
attribute
()
default
""
;
}
hutool-core/src/main/java/cn/hutool/core/annotation/ForceAliasedAnnotationAttribute.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
/**
* 表示一个被指定了强制别名的注解属性。
* 当调用{@link #getValue()}时,总是返回{@link #linked}的值
*
* @author huangchengxing
* @see AliasAnnotationPostProcessor
* @see AliasLinkAnnotationPostProcessor
* @see RelationType#ALIAS_FOR
* @see RelationType#FORCE_ALIAS_FOR
*/
public
class
ForceAliasedAnnotationAttribute
extends
AbstractWrappedAnnotationAttribute
{
protected
ForceAliasedAnnotationAttribute
(
AnnotationAttribute
origin
,
AnnotationAttribute
linked
)
{
super
(
origin
,
linked
);
}
/**
* 总是返回{@link #linked}的{@link AnnotationAttribute#getValue()}的返回值
*
* @return {@link #linked}的{@link AnnotationAttribute#getValue()}的返回值
*/
@Override
public
Object
getValue
()
{
return
linked
.
getValue
();
}
/**
* 总是返回{@link #linked}的{@link AnnotationAttribute#isValueEquivalentToDefaultValue()}的返回值
*
* @return {@link #linked}的{@link AnnotationAttribute#isValueEquivalentToDefaultValue()}的返回值
*/
@Override
public
boolean
isValueEquivalentToDefaultValue
()
{
return
linked
.
isValueEquivalentToDefaultValue
();
}
/**
* 总是返回{@link #linked}的{@link AnnotationAttribute#getAttributeType()}的返回值
*
* @return {@link #linked}的{@link AnnotationAttribute#getAttributeType()}的返回值
*/
@Override
public
Class
<?>
getAttributeType
()
{
return
linked
.
getAttributeType
();
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAggregateAnnotation.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.annotation.scanner.AnnotationScanner
;
import
cn.hutool.core.annotation.scanner.MetaAnnotationScanner
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.lang.Opt
;
import
cn.hutool.core.util.ObjectUtil
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.AnnotatedElement
;
import
java.util.*
;
/**
* {@link SynthesizedAggregateAnnotation}的基本实现,表示基于多个注解对象,
* 或多个根注解对象与他们的多层元注解对象的聚合得到的注解。
*
* <p>假设现有注解A,若指定的{@link #annotationScanner}支持扫描注解A的元注解,
* 且A上存在元注解B,B上存在元注解C,则对注解A进行解析,将得到包含根注解A,以及其元注解B、C在内的合成元注解聚合{@link GenericSynthesizedAggregateAnnotation}。
* 从{@link AnnotatedElement}的角度来说,得到的合成注解是一个同时承载有ABC三个注解对象的被注解元素,
* 因此通过调用{@link AnnotatedElement}的相关方法将返回对应符合语义的注解对象。
*
* <p>在扫描指定根注解及其元注解时,若在不同的层级出现了类型相同的注解实例,
* 将会根据实例化时指定的{@link SynthesizedAnnotationSelector}选择最优的注解,
* 完成对根注解及其元注解的扫描后,合成注解中每种类型的注解对象都将有且仅有一个。<br>
* 默认情况下,将使用{@link SynthesizedAnnotationSelector#NEAREST_AND_OLDEST_PRIORITY}作为选择器,
* 此时若出现扫描时得到了多个同类型的注解对象,有且仅有最接近根注解的注解对象会被作为有效注解。
*
* <p>当扫描的注解对象经过{@link SynthesizedAnnotationSelector}处理后,
* 将会被转为{@link MetaAnnotation},并使用在实例化时指定的{@link AliasAnnotationPostProcessor}
* 进行后置处理。<br>
* 默认情况下,将注册以下后置处理器以对{@link Alias}与{@link Link}和其扩展注解提供支持:
* <ul>
* <li>{@link AliasAnnotationPostProcessor};</li>
* <li>{@link MirrorLinkAnnotationPostProcessor};</li>
* <li>{@link AliasLinkAnnotationPostProcessor};</li>
* </ul>
* 若用户需要自行扩展,则需要保证上述三个处理器被正确注入当前实例。
*
* <p>{@link GenericSynthesizedAggregateAnnotation}支持通过{@link #getAttributeValue(String, Class)},
* 或通过{@link #synthesize(Class)}获得注解代理对象后获取指定类型的注解属性值,
* 返回的属性值将根据合成注解中对应原始注解属性上的{@link Alias}与{@link Link}注解而有所变化。
* 通过当前实例获取属性值时,将经过{@link SynthesizedAnnotationAttributeProcessor}的处理。<br>
* 默认情况下,实例将会注册{@link CacheableSynthesizedAnnotationAttributeProcessor},
* 该处理器将令元注解中与子注解类型与名称皆一致的属性被子注解的属性覆盖,并且缓存最终获取到的属性值。
*
* @author huangchengxing
* @see AnnotationUtil
* @see SynthesizedAnnotationProxy
* @see SynthesizedAnnotationSelector
* @see SynthesizedAnnotationAttributeProcessor
* @see SynthesizedAnnotationPostProcessor
* @see AnnotationSynthesizer
* @see AnnotationScanner
*/
public
class
GenericSynthesizedAggregateAnnotation
extends
AbstractAnnotationSynthesizer
<
List
<
Annotation
>>
implements
SynthesizedAggregateAnnotation
{
/**
* 根对象
*/
private
final
Object
root
;
/**
* 距离根对象的垂直距离
*/
private
final
int
verticalDistance
;
/**
* 距离根对象的水平距离
*/
private
final
int
horizontalDistance
;
/**
* 合成注解属性处理器
*/
private
final
SynthesizedAnnotationAttributeProcessor
attributeProcessor
;
/**
* 基于指定根注解,为其与其元注解的层级结构中的全部注解构造一个合成注解。
* 当层级结构中出现了相同的注解对象时,将优先选择以距离根注解最近,且优先被扫描的注解对象,
* 当获取值时,同样遵循该规则。
*
* @param source 源注解
*/
public
GenericSynthesizedAggregateAnnotation
(
Annotation
...
source
)
{
this
(
Arrays
.
asList
(
source
),
new
MetaAnnotationScanner
());
}
/**
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解。
* 若扫描器支持对注解的层级结构进行扫描,则若层级结构中出现了相同的注解对象时,
* 将优先选择以距离根注解最近,且优先被扫描的注解对象,并且当获取注解属性值时同样遵循该规则。
*
* @param source 源注解
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
*/
public
GenericSynthesizedAggregateAnnotation
(
List
<
Annotation
>
source
,
AnnotationScanner
annotationScanner
)
{
this
(
source
,
SynthesizedAnnotationSelector
.
NEAREST_AND_OLDEST_PRIORITY
,
new
CacheableSynthesizedAnnotationAttributeProcessor
(),
Arrays
.
asList
(
SynthesizedAnnotationPostProcessor
.
ALIAS_ANNOTATION_POST_PROCESSOR
,
SynthesizedAnnotationPostProcessor
.
MIRROR_LINK_ANNOTATION_POST_PROCESSOR
,
SynthesizedAnnotationPostProcessor
.
ALIAS_LINK_ANNOTATION_POST_PROCESSOR
),
annotationScanner
);
}
/**
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解
*
* @param source 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param attributeProcessor 注解属性处理器
* @param annotationPostProcessors 注解后置处理器
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
*/
public
GenericSynthesizedAggregateAnnotation
(
List
<
Annotation
>
source
,
SynthesizedAnnotationSelector
annotationSelector
,
SynthesizedAnnotationAttributeProcessor
attributeProcessor
,
Collection
<
SynthesizedAnnotationPostProcessor
>
annotationPostProcessors
,
AnnotationScanner
annotationScanner
)
{
this
(
null
,
0
,
0
,
source
,
annotationSelector
,
attributeProcessor
,
annotationPostProcessors
,
annotationScanner
);
}
/**
* 基于指定根注解,为其层级结构中的全部注解构造一个合成注解
*
* @param root 根对象
* @param verticalDistance 距离根对象的水平距离
* @param horizontalDistance 距离根对象的垂直距离
* @param source 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param attributeProcessor 注解属性处理器
* @param annotationPostProcessors 注解后置处理器
* @param annotationScanner 注解扫描器,该扫描器必须支持扫描注解类
*/
GenericSynthesizedAggregateAnnotation
(
Object
root
,
int
verticalDistance
,
int
horizontalDistance
,
List
<
Annotation
>
source
,
SynthesizedAnnotationSelector
annotationSelector
,
SynthesizedAnnotationAttributeProcessor
attributeProcessor
,
Collection
<
SynthesizedAnnotationPostProcessor
>
annotationPostProcessors
,
AnnotationScanner
annotationScanner
)
{
super
(
source
,
annotationSelector
,
annotationPostProcessors
,
annotationScanner
);
Assert
.
notNull
(
attributeProcessor
,
"attributeProcessor must not null"
);
this
.
root
=
ObjectUtil
.
defaultIfNull
(
root
,
this
);
this
.
verticalDistance
=
verticalDistance
;
this
.
horizontalDistance
=
horizontalDistance
;
this
.
attributeProcessor
=
attributeProcessor
;
}
/**
* 获取根对象
*
* @return 根对象
*/
@Override
public
Object
getRoot
()
{
return
root
;
}
/**
* 获取与根对象的垂直距离
*
* @return 与根对象的垂直距离
*/
@Override
public
int
getVerticalDistance
()
{
return
verticalDistance
;
}
/**
* 获取与根对象的水平距离
*
* @return 获取与根对象的水平距离
*/
@Override
public
int
getHorizontalDistance
()
{
return
horizontalDistance
;
}
/**
* 按广度优先扫描{@link #source}上的元注解
*/
@Override
protected
Map
<
Class
<?
extends
Annotation
>,
SynthesizedAnnotation
>
loadAnnotations
()
{
Map
<
Class
<?
extends
Annotation
>,
SynthesizedAnnotation
>
annotationMap
=
new
LinkedHashMap
<>();
// 根注解默认水平坐标为0,根注解的元注解坐标从1开始
for
(
int
i
=
0
;
i
<
source
.
size
();
i
++)
{
final
Annotation
sourceAnnotation
=
source
.
get
(
i
);
Assert
.
isFalse
(
AnnotationUtil
.
isSynthesizedAnnotation
(
sourceAnnotation
),
"source [{}] has been synthesized"
);
annotationMap
.
put
(
sourceAnnotation
.
annotationType
(),
new
MetaAnnotation
(
sourceAnnotation
,
sourceAnnotation
,
0
,
i
));
Assert
.
isTrue
(
annotationScanner
.
support
(
sourceAnnotation
.
annotationType
()),
"annotation scanner [{}] cannot support scan [{}]"
,
annotationScanner
,
sourceAnnotation
.
annotationType
()
);
annotationScanner
.
scan
(
(
index
,
annotation
)
->
{
SynthesizedAnnotation
oldAnnotation
=
annotationMap
.
get
(
annotation
.
annotationType
());
SynthesizedAnnotation
newAnnotation
=
new
MetaAnnotation
(
sourceAnnotation
,
annotation
,
index
+
1
,
annotationMap
.
size
());
if
(
ObjectUtil
.
isNull
(
oldAnnotation
))
{
annotationMap
.
put
(
annotation
.
annotationType
(),
newAnnotation
);
}
else
{
annotationMap
.
put
(
annotation
.
annotationType
(),
annotationSelector
.
choose
(
oldAnnotation
,
newAnnotation
));
}
},
sourceAnnotation
.
annotationType
(),
null
);
}
return
annotationMap
;
}
/**
* 获取合成注解属性处理器
*
* @return 合成注解属性处理器
*/
@Override
public
SynthesizedAnnotationAttributeProcessor
getAnnotationAttributeProcessor
()
{
return
this
.
attributeProcessor
;
}
/**
* 根据指定的属性名与属性类型获取对应的属性值,若存在{@link Alias}则获取{@link Alias#value()}指定的别名属性的值
* <p>当不同层级的注解之间存在同名同类型属性时,将优先获取更接近根注解的属性
*
* @param attributeName 属性名
* @param attributeType 属性类型
* @return 属性
*/
@Override
public
Object
getAttributeValue
(
String
attributeName
,
Class
<?>
attributeType
)
{
return
attributeProcessor
.
getAttributeValue
(
attributeName
,
attributeType
,
synthesizedAnnotationMap
.
values
());
}
/**
* 获取合成注解中包含的指定注解
*
* @param annotationType 注解类型
* @param <T> 注解类型
* @return 注解对象
*/
@Override
public
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotationType
)
{
return
Opt
.
ofNullable
(
annotationType
)
.
map
(
synthesizedAnnotationMap:
:
get
)
.
map
(
SynthesizedAnnotation:
:
getAnnotation
)
.
map
(
annotationType:
:
cast
)
.
orElse
(
null
);
}
/**
* 当前合成注解中是否存在指定元注解
*
* @param annotationType 注解类型
* @return 是否
*/
@Override
public
boolean
isAnnotationPresent
(
Class
<?
extends
Annotation
>
annotationType
)
{
return
synthesizedAnnotationMap
.
containsKey
(
annotationType
);
}
/**
* 获取合成注解中包含的全部注解
*
* @return 注解对象
*/
@Override
public
Annotation
[]
getAnnotations
()
{
return
synthesizedAnnotationMap
.
values
().
stream
()
.
map
(
SynthesizedAnnotation:
:
getAnnotation
)
.
toArray
(
Annotation
[]::
new
);
}
/**
* 若合成注解在存在指定元注解,则使用动态代理生成一个对应的注解实例
*
* @param annotationType 注解类型
* @return 合成注解对象
* @see SynthesizedAnnotationProxy#create(Class, AnnotationAttributeValueProvider, SynthesizedAnnotation)
*/
@Override
public
<
T
extends
Annotation
>
T
synthesize
(
Class
<
T
>
annotationType
,
SynthesizedAnnotation
annotation
)
{
return
SynthesizedAnnotationProxy
.
create
(
annotationType
,
this
,
annotation
);
}
/**
* 注解包装类,表示{@link #source}以及{@link #source}所属层级结构中的全部关联注解对象
*
* @author huangchengxing
*/
public
static
class
MetaAnnotation
extends
GenericSynthesizedAnnotation
<
Annotation
,
Annotation
>
{
/**
* 创建一个合成注解
*
* @param root 根对象
* @param annotation 被合成的注解对象
* @param verticalDistance 距离根对象的水平距离
* @param horizontalDistance 距离根对象的垂直距离
*/
protected
MetaAnnotation
(
Annotation
root
,
Annotation
annotation
,
int
verticalDistance
,
int
horizontalDistance
)
{
super
(
root
,
annotation
,
verticalDistance
,
horizontalDistance
);
}
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.lang.Opt
;
import
cn.hutool.core.util.ClassUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Method
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.function.UnaryOperator
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
/**
* {@link SynthesizedAnnotation}的基本实现
*
* @param <R> 根对象类型
* @param <T> 注解类型
* @author huangchengxing
*/
public
class
GenericSynthesizedAnnotation
<
R
,
T
extends
Annotation
>
implements
SynthesizedAnnotation
{
private
final
R
root
;
private
final
T
annotation
;
private
final
Map
<
String
,
AnnotationAttribute
>
attributeMethodCaches
;
private
final
int
verticalDistance
;
private
final
int
horizontalDistance
;
/**
* 创建一个合成注解
*
* @param root 根对象
* @param annotation 被合成的注解对象
* @param verticalDistance 距离根对象的水平距离
* @param horizontalDistance 距离根对象的垂直距离
*/
protected
GenericSynthesizedAnnotation
(
R
root
,
T
annotation
,
int
verticalDistance
,
int
horizontalDistance
)
{
this
.
root
=
root
;
this
.
annotation
=
annotation
;
this
.
verticalDistance
=
verticalDistance
;
this
.
horizontalDistance
=
horizontalDistance
;
this
.
attributeMethodCaches
=
new
HashMap
<>();
this
.
attributeMethodCaches
.
putAll
(
loadAttributeMethods
());
}
/**
* 加载注解属性
*
* @return 注解属性
*/
protected
Map
<
String
,
AnnotationAttribute
>
loadAttributeMethods
()
{
return
Stream
.
of
(
ClassUtil
.
getDeclaredMethods
(
annotation
.
annotationType
()))
.
filter
(
AnnotationUtil:
:
isAttributeMethod
)
.
collect
(
Collectors
.
toMap
(
Method:
:
getName
,
method
->
new
CacheableAnnotationAttribute
(
annotation
,
method
)));
}
/**
* 元注解是否存在该属性
*
* @param attributeName 属性名
* @return 是否存在该属性
*/
public
boolean
hasAttribute
(
String
attributeName
)
{
return
attributeMethodCaches
.
containsKey
(
attributeName
);
}
/**
* 元注解是否存在该属性,且该属性的值类型是指定类型或其子类
*
* @param attributeName 属性名
* @param returnType 返回值类型
* @return 是否存在该属性
*/
@Override
public
boolean
hasAttribute
(
String
attributeName
,
Class
<?>
returnType
)
{
return
Opt
.
ofNullable
(
attributeMethodCaches
.
get
(
attributeName
))
.
filter
(
method
->
ClassUtil
.
isAssignable
(
returnType
,
method
.
getAttributeType
()))
.
isPresent
();
}
/**
* 获取该注解的全部属性
*
* @return 注解属性
*/
@Override
public
Map
<
String
,
AnnotationAttribute
>
getAttributes
()
{
return
this
.
attributeMethodCaches
;
}
/**
* 设置属性值
*
* @param attributeName 属性名称
* @param attribute 注解属性
*/
@Override
public
void
setAttribute
(
String
attributeName
,
AnnotationAttribute
attribute
)
{
attributeMethodCaches
.
put
(
attributeName
,
attribute
);
}
/**
* 替换属性值
*
* @param attributeName 属性名
* @param operator 替换操作
*/
@Override
public
void
replaceAttribute
(
String
attributeName
,
UnaryOperator
<
AnnotationAttribute
>
operator
)
{
AnnotationAttribute
old
=
attributeMethodCaches
.
get
(
attributeName
);
if
(
ObjectUtil
.
isNotNull
(
old
))
{
attributeMethodCaches
.
put
(
attributeName
,
operator
.
apply
(
old
));
}
}
/**
* 获取属性值
*
* @param attributeName 属性名
* @return 属性值
*/
@Override
public
Object
getAttributeValue
(
String
attributeName
)
{
return
Opt
.
ofNullable
(
attributeMethodCaches
.
get
(
attributeName
))
.
map
(
AnnotationAttribute:
:
getValue
)
.
get
();
}
/**
* 获取该合成注解对应的根节点
*
* @return 合成注解对应的根节点
*/
@Override
public
R
getRoot
()
{
return
root
;
}
/**
* 获取被合成的注解对象
*
* @return 注解对象
*/
@Override
public
T
getAnnotation
()
{
return
annotation
;
}
/**
* 获取该合成注解与根对象的垂直距离。
* 默认情况下,该距离即为当前注解与根对象之间相隔的层级数。
*
* @return 合成注解与根对象的垂直距离
*/
@Override
public
int
getVerticalDistance
()
{
return
verticalDistance
;
}
/**
* 获取该合成注解与根对象的水平距离。
* 默认情况下,该距离即为当前注解与根对象之间相隔的已经被扫描到的注解数。
*
* @return 合成注解与根对象的水平距离
*/
@Override
public
int
getHorizontalDistance
()
{
return
horizontalDistance
;
}
/**
* 获取被合成的注解类型
*
* @return 被合成的注解类型
*/
@Override
public
Class
<?
extends
Annotation
>
annotationType
()
{
return
annotation
.
annotationType
();
}
/**
* 获取注解属性值
*
* @param attributeName 属性名称
* @param attributeType 属性类型
* @return 注解属性值
*/
@Override
public
Object
getAttributeValue
(
String
attributeName
,
Class
<?>
attributeType
)
{
return
Opt
.
ofNullable
(
attributeMethodCaches
.
get
(
attributeName
))
.
filter
(
method
->
ClassUtil
.
isAssignable
(
attributeType
,
method
.
getAttributeType
()))
.
map
(
AnnotationAttribute:
:
getValue
)
.
get
();
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/Hierarchical.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.util.Comparator
;
/**
* <p>描述以一个参照物为对象,存在于该参照物的层级结构中的对象。
*
* <p>该对象可通过{@link #getVerticalDistance()}与{@link #getHorizontalDistance()}
* 描述其在以参照物为基点的坐标坐标系中的位置。<br>
* 在需要对该接口的实现类进行按优先级排序时,距离{@link #getRoot()}对象越近,则该实现类的优先级越高。
* 默认提供了{@link #DEFAULT_HIERARCHICAL_COMPARATOR}用于实现该比较规则。<br>
* 一般情况下,{@link #getRoot()}返回值相同的对象之间的比较才有意义。
*
* <p>此外,还提供了{@link Selector}接口用于根据一定的规则从两个{@link Hierarchical}实现类中选择并返回一个最合适的对象,
* 默认提供了四个实现类:
* <ul>
* <li>{@link Selector#NEAREST_AND_OLDEST_PRIORITY}: 返回距离根对象更近的对象,当距离一样时优先返回旧对象;</li>
* <li>{@link Selector#NEAREST_AND_NEWEST_PRIORITY}: 返回距离根对象更近的对象,当距离一样时优先返回新对象;</li>
* <li>{@link Selector#FARTHEST_AND_OLDEST_PRIORITY}: 返回距离根对象更远的对象,当距离一样时优先返回旧对象;</li>
* <li>{@link Selector#FARTHEST_AND_NEWEST_PRIORITY}: 返回距离根对象更远的对象,当距离一样时优先返回新对象;</li>
* </ul>
*
* @author huangchengxing
*/
public
interface
Hierarchical
extends
Comparable
<
Hierarchical
>
{
// ====================== compare ======================
/**
* 默认{@link #getHorizontalDistance()}与{@link #getVerticalDistance()}排序的比较器
*/
Comparator
<
Hierarchical
>
DEFAULT_HIERARCHICAL_COMPARATOR
=
Comparator
.
comparing
(
Hierarchical:
:
getVerticalDistance
)
.
thenComparing
(
Hierarchical:
:
getHorizontalDistance
);
/**
* 按{@link #getVerticalDistance()}和{@link #getHorizontalDistance()}排序
*
* @param o {@link SynthesizedAnnotation}对象
* @return 比较值
*/
@Override
default
int
compareTo
(
Hierarchical
o
)
{
return
DEFAULT_HIERARCHICAL_COMPARATOR
.
compare
(
this
,
o
);
}
// ====================== hierarchical ======================
/**
* 参照物,即坐标为{@code (0, 0)}的对象。
* 当对象本身即为参照物时,该方法应当返回其本身
*
* @return 参照物
*/
Object
getRoot
();
/**
* 获取该对象与参照物的垂直距离。
* 默认情况下,该距离即为当前对象与参照物之间相隔的层级数。
*
* @return 合成注解与根对象的垂直距离
*/
int
getVerticalDistance
();
/**
* 获取该对象与参照物的水平距离。
* 默认情况下,该距离即为当前对象在与参照物{@link #getVerticalDistance()}相同的情况下条,
* 该对象被扫描到的顺序。
*
* @return 合成注解与根对象的水平距离
*/
int
getHorizontalDistance
();
// ====================== selector ======================
/**
* {@link Hierarchical}选择器,用于根据一定的规则从两个{@link Hierarchical}实现类中选择并返回一个最合适的对象
*/
@FunctionalInterface
interface
Selector
{
/**
* 返回距离根对象更近的对象,当距离一样时优先返回旧对象
*/
Selector
NEAREST_AND_OLDEST_PRIORITY
=
new
NearestAndOldestPrioritySelector
();
/**
* 返回距离根对象更近的对象,当距离一样时优先返回新对象
*/
Selector
NEAREST_AND_NEWEST_PRIORITY
=
new
NearestAndNewestPrioritySelector
();
/**
* 返回距离根对象更远的对象,当距离一样时优先返回旧对象
*/
Selector
FARTHEST_AND_OLDEST_PRIORITY
=
new
FarthestAndOldestPrioritySelector
();
/**
* 返回距离根对象更远的对象,当距离一样时优先返回新对象
*/
Selector
FARTHEST_AND_NEWEST_PRIORITY
=
new
FarthestAndNewestPrioritySelector
();
/**
* 比较两个被合成的对象,选择其中的一个并返回
*
* @param <T> 复合注解类型
* @param prev 上一对象,该参数不允许为空
* @param next 下一对象,该参数不允许为空
* @return 对象
*/
<
T
extends
Hierarchical
>
T
choose
(
T
prev
,
T
next
);
/**
* 返回距离根对象更近的注解,当距离一样时优先返回旧注解
*/
class
NearestAndOldestPrioritySelector
implements
Selector
{
@Override
public
<
T
extends
Hierarchical
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
newAnnotation
.
getVerticalDistance
()
<
oldAnnotation
.
getVerticalDistance
()
?
newAnnotation
:
oldAnnotation
;
}
}
/**
* 返回距离根对象更近的注解,当距离一样时优先返回新注解
*/
class
NearestAndNewestPrioritySelector
implements
Selector
{
@Override
public
<
T
extends
Hierarchical
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
newAnnotation
.
getVerticalDistance
()
<=
oldAnnotation
.
getVerticalDistance
()
?
newAnnotation
:
oldAnnotation
;
}
}
/**
* 返回距离根对象更远的注解,当距离一样时优先返回旧注解
*/
class
FarthestAndOldestPrioritySelector
implements
Selector
{
@Override
public
<
T
extends
Hierarchical
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
newAnnotation
.
getVerticalDistance
()
>
oldAnnotation
.
getVerticalDistance
()
?
newAnnotation
:
oldAnnotation
;
}
}
/**
* 返回距离根对象更远的注解,当距离一样时优先返回新注解
*/
class
FarthestAndNewestPrioritySelector
implements
Selector
{
@Override
public
<
T
extends
Hierarchical
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
newAnnotation
.
getVerticalDistance
()
>=
oldAnnotation
.
getVerticalDistance
()
?
newAnnotation
:
oldAnnotation
;
}
}
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/Link.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.*
;
/**
* <p>用于在同一注解中,或具有一定关联的不同注解的属性中,表明这些属性之间具有特定的关联关系。
* 在通过{@link SynthesizedAggregateAnnotation}获取合成注解后,合成注解获取属性值时会根据该注解进行调整。<br>
*
* <p>该注解存在三个字注解:{@link MirrorFor}、{@link ForceAliasFor}或{@link AliasFor},
* 使用三个子注解等同于{@link Link}。但是需要注意的是,
* 当注解中的属性同时存在多个{@link Link}或基于{@link Link}的子注解时,
* 仅有声明在被注解的属性最上方的注解会生效,其余注解都将被忽略。
*
* <b>注意:该注解的优先级低于{@link Alias}</b>
*
* @author huangchengxing
* @see SynthesizedAggregateAnnotation
* @see RelationType
* @see AliasFor
* @see MirrorFor
* @see ForceAliasFor
*/
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
public
@interface
Link
{
/**
* 产生关联的注解类型,当不指定时,默认指注释的属性所在的类
*
* @return 关联的注解类型
*/
Class
<?
extends
Annotation
>
annotation
()
default
Annotation
.
class
;
/**
* {@link #annotation()}指定注解中关联的属性
*
* @return 属性名
*/
String
attribute
()
default
""
;
/**
* {@link #attribute()}指定属性与当前注解的属性建的关联关系类型
*
* @return 关系类型
*/
RelationType
type
()
default
RelationType
.
MIRROR_FOR
;
}
hutool-core/src/main/java/cn/hutool/core/annotation/MirrorFor.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.*
;
/**
* <p>{@link Link}的子注解。表示注解的属性与指定的属性互为镜像,通过一个属性将能够获得对方的值。<br>
* 它们遵循下述规则:
* <ul>
* <li>互为镜像的两个属性,必须同时通过指定模式为{@code MIRROR_FOR}的{@link Link}注解指定对方;</li>
* <li>互为镜像的两个属性,类型必须一致;</li>
* <li>互为镜像的两个属性在获取值,且两者的值皆不同时,必须且仅允许有一个非默认值,该值被优先返回;</li>
* <li>互为镜像的两个属性,在值都为默认值或都不为默认值时,两者的值必须相等;</li>
* </ul>
* <b>注意,该注解与{@link Link}、{@link ForceAliasFor}或{@link AliasFor}一起使用时,将只有被声明在最上面的注解会生效</b>
*
* @author huangchengxing
* @see Link
* @see RelationType#MIRROR_FOR
*/
@Link
(
type
=
RelationType
.
MIRROR_FOR
)
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
public
@interface
MirrorFor
{
/**
* 产生关联的注解类型,当不指定时,默认指注释的属性所在的类
*
* @return 关联的注解类型
*/
@Link
(
annotation
=
Link
.
class
,
attribute
=
"annotation"
,
type
=
RelationType
.
FORCE_ALIAS_FOR
)
Class
<?
extends
Annotation
>
annotation
()
default
Annotation
.
class
;
/**
* {@link #annotation()}指定注解中关联的属性
*
* @return 属性名
*/
@Link
(
annotation
=
Link
.
class
,
attribute
=
"attribute"
,
type
=
RelationType
.
FORCE_ALIAS_FOR
)
String
attribute
()
default
""
;
}
hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.text.CharSequenceUtil
;
import
cn.hutool.core.util.ObjectUtil
;
/**
* <p>用于处理注解对象中带有{@link Link}注解,且{@link Link#type()}为{@link RelationType#MIRROR_FOR}的属性。<br>
* 当该处理器执行完毕后,原始合成注解中被{@link Link}注解的属性与{@link Link}注解指向的目标注解的属性,
* 都将会被被包装并替换为{@link MirroredAnnotationAttribute}。
*
* @author huangchengxing
* @see RelationType#MIRROR_FOR
* @see MirroredAnnotationAttribute
*/
public
class
MirrorLinkAnnotationPostProcessor
extends
AbstractLinkAnnotationPostProcessor
{
private
static
final
RelationType
[]
PROCESSED_RELATION_TYPES
=
new
RelationType
[]{
RelationType
.
MIRROR_FOR
};
@Override
public
int
order
()
{
return
Integer
.
MIN_VALUE
+
1
;
}
/**
* 该处理器只处理{@link Link#type()}类型为{@link RelationType#MIRROR_FOR}的注解属性
*
* @return 仅有{@link RelationType#MIRROR_FOR}数组
*/
@Override
protected
RelationType
[]
processTypes
()
{
return
PROCESSED_RELATION_TYPES
;
}
/**
* 将存在镜像关系的合成注解属性分别包装为{@link MirroredAnnotationAttribute}对象,
* 并使用包装后{@link MirroredAnnotationAttribute}替换在它们对应合成注解实例中的{@link AnnotationAttribute}
*
* @param synthesizer 注解合成器
* @param annotation {@code originalAttribute}上的{@link Link}注解对象
* @param originalAnnotation 当前正在处理的{@link SynthesizedAnnotation}对象
* @param originalAttribute {@code originalAnnotation}上的待处理的属性
* @param linkedAnnotation {@link Link}指向的关联注解对象
* @param linkedAttribute {@link Link}指向的{@code originalAnnotation}中的关联属性,该参数可能为空
*/
@Override
protected
void
processLinkedAttribute
(
AnnotationSynthesizer
synthesizer
,
Link
annotation
,
SynthesizedAnnotation
originalAnnotation
,
AnnotationAttribute
originalAttribute
,
SynthesizedAnnotation
linkedAnnotation
,
AnnotationAttribute
linkedAttribute
)
{
// 镜像属性必然成对出现,因此此处必定存在三种情况:
// 1.两属性都不为镜像属性,此时继续进行后续处理;
// 2.两属性都为镜像属性,并且指向对方,此时无需后续处理;
// 3.两属性仅有任意一属性为镜像属性,此时镜像属性必然未指向当前原始属性,此时应该抛出异常;
if
(
originalAttribute
instanceof
MirroredAnnotationAttribute
||
linkedAttribute
instanceof
MirroredAnnotationAttribute
)
{
checkMirrored
(
originalAttribute
,
linkedAttribute
);
return
;
}
// 校验镜像关系
checkMirrorRelation
(
annotation
,
originalAttribute
,
linkedAttribute
);
// 包装这一对镜像属性,并替换原注解中的对应属性
final
AnnotationAttribute
mirroredOriginalAttribute
=
new
MirroredAnnotationAttribute
(
originalAttribute
,
linkedAttribute
);
originalAnnotation
.
setAttribute
(
originalAttribute
.
getAttributeName
(),
mirroredOriginalAttribute
);
final
AnnotationAttribute
mirroredTargetAttribute
=
new
MirroredAnnotationAttribute
(
linkedAttribute
,
originalAttribute
);
linkedAnnotation
.
setAttribute
(
annotation
.
attribute
(),
mirroredTargetAttribute
);
}
/**
* 检查映射关系是否正确
*/
private
void
checkMirrored
(
AnnotationAttribute
original
,
AnnotationAttribute
mirror
)
{
final
boolean
originalAttributeMirrored
=
original
instanceof
MirroredAnnotationAttribute
;
final
boolean
mirrorAttributeMirrored
=
mirror
instanceof
MirroredAnnotationAttribute
;
// 校验通过
final
boolean
passed
=
originalAttributeMirrored
&&
mirrorAttributeMirrored
&&
ObjectUtil
.
equals
(((
MirroredAnnotationAttribute
)
original
).
getLinked
(),
((
MirroredAnnotationAttribute
)
mirror
).
getOriginal
());
if
(
passed
)
{
return
;
}
// 校验失败,拼装异常信息用于抛出异常
String
errorMsg
;
// 原始字段已经跟其他字段形成镜像
if
(
originalAttributeMirrored
&&
!
mirrorAttributeMirrored
)
{
errorMsg
=
CharSequenceUtil
.
format
(
"attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}]"
,
original
.
getAttribute
(),
mirror
.
getAttribute
(),
((
MirroredAnnotationAttribute
)
original
).
getLinked
()
);
}
// 镜像字段已经跟其他字段形成镜像
else
if
(!
originalAttributeMirrored
&&
mirrorAttributeMirrored
)
{
errorMsg
=
CharSequenceUtil
.
format
(
"attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}]"
,
mirror
.
getAttribute
(),
original
.
getAttribute
(),
((
MirroredAnnotationAttribute
)
mirror
).
getLinked
()
);
}
// 两者都形成了镜像,但是都未指向对方,理论上不会存在该情况
else
{
errorMsg
=
CharSequenceUtil
.
format
(
"attribute [{}] cannot mirror for [{}], because [{}] already mirrored for [{}] and [{}] already mirrored for [{}]"
,
mirror
.
getAttribute
(),
original
.
getAttribute
(),
mirror
.
getAttribute
(),
((
MirroredAnnotationAttribute
)
mirror
).
getLinked
(),
original
.
getAttribute
(),
((
MirroredAnnotationAttribute
)
original
).
getLinked
()
);
}
throw
new
IllegalArgumentException
(
errorMsg
);
}
/**
* 基本校验
*/
private
void
checkMirrorRelation
(
Link
annotation
,
AnnotationAttribute
original
,
AnnotationAttribute
mirror
)
{
// 镜像属性必须存在
checkLinkedAttributeNotNull
(
original
,
mirror
,
annotation
);
// 镜像属性返回值必须一致
checkAttributeType
(
original
,
mirror
);
// 镜像属性上必须存在对应的注解
final
Link
mirrorAttributeAnnotation
=
getLinkAnnotation
(
mirror
,
RelationType
.
MIRROR_FOR
);
Assert
.
isTrue
(
ObjectUtil
.
isNotNull
(
mirrorAttributeAnnotation
)
&&
RelationType
.
MIRROR_FOR
.
equals
(
mirrorAttributeAnnotation
.
type
()),
"mirror attribute [{}] of original attribute [{}] must marked by @Link, and also @LinkType.type() must is [{}]"
,
mirror
.
getAttribute
(),
original
.
getAttribute
(),
RelationType
.
MIRROR_FOR
);
checkLinkedSelf
(
original
,
mirror
);
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/MirroredAnnotationAttribute.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.lang.Assert
;
/**
* 表示存在对应镜像属性的注解属性,当获取值时将根据{@link RelationType#MIRROR_FOR}的规则进行处理
*
* @author huangchengxing
* @see MirrorLinkAnnotationPostProcessor
* @see RelationType#MIRROR_FOR
*/
public
class
MirroredAnnotationAttribute
extends
AbstractWrappedAnnotationAttribute
{
public
MirroredAnnotationAttribute
(
AnnotationAttribute
origin
,
AnnotationAttribute
linked
)
{
super
(
origin
,
linked
);
}
@Override
public
Object
getValue
()
{
final
boolean
originIsDefault
=
original
.
isValueEquivalentToDefaultValue
();
final
boolean
targetIsDefault
=
linked
.
isValueEquivalentToDefaultValue
();
final
Object
originValue
=
original
.
getValue
();
final
Object
targetValue
=
linked
.
getValue
();
// 都为默认值,或都为非默认值时,两方法的返回值必须相等
if
(
originIsDefault
==
targetIsDefault
)
{
Assert
.
equals
(
originValue
,
targetValue
,
"the values of attributes [{}] and [{}] that mirror each other are different: [{}] <==> [{}]"
,
original
.
getAttribute
(),
linked
.
getAttribute
(),
originValue
,
targetValue
);
return
originValue
;
}
// 两者有一者不为默认值时,优先返回非默认值
return
originIsDefault
?
targetValue
:
originValue
;
}
/**
* 当{@link #original}与{@link #linked}都为默认值时返回{@code true}
*
* @return 是否
*/
@Override
public
boolean
isValueEquivalentToDefaultValue
()
{
return
original
.
isValueEquivalentToDefaultValue
()
&&
linked
.
isValueEquivalentToDefaultValue
();
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/PropIgnore.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* 属性忽略注解,使用此注解的字段等会被忽略,主要用于Bean拷贝、Bean转Map等<br>
* 此注解应用于字段时,忽略读取和设置属性值,应用于setXXX方法忽略设置值,应用于getXXX忽略读取值
*
* @author Looly
* @since 5.4.2
*/
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
FIELD
,
ElementType
.
PARAMETER
})
public
@interface
PropIgnore
{
}
hutool-core/src/main/java/cn/hutool/core/annotation/RelationType.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
/**
* <p>注解属性的关系类型 <br>
* 若将被{@link Link}注解的属性称为“原始属性”,而在{@link Link}注解中指向的注解属性称为“关联属性”,
* 则该枚举用于描述“原始属性”与“关联属性”在{@link SynthesizedAggregateAnnotation}处理过程中的作用关系。<br>
* 根据在{@link Link#type()}中指定的关系类型的不同,通过{@link SynthesizedAggregateAnnotation}合成的注解的属性值也将有所变化。
*
* <p>当一个注解中的所有属性同时具备多种关系时,将依次按下述顺序处理:
* <ol>
* <li>属性上的{@link Alias}注解;</li>
* <li>属性上的{@link Link}注解,且{@link Link#type()}为{@link #MIRROR_FOR};</li>
* <li>属性上的{@link Link}注解,且{@link Link#type()}为{@link #FORCE_ALIAS_FOR};</li>
* <li>属性上的{@link Link}注解,且{@link Link#type()}为{@link #ALIAS_FOR};</li>
* </ol>
*
* @author huangchengxing
* @see SynthesizedAggregateAnnotation
* @see Link
*/
public
enum
RelationType
{
/**
* <p>表示注解的属性与指定的属性互为镜像,通过一个属性将能够获得对方的值。<br>
* 它们遵循下述规则:
* <ul>
* <li>互为镜像的两个属性,必须同时通过指定模式为{@code MIRROR_FOR}的{@link Link}注解指定对方;</li>
* <li>互为镜像的两个属性,类型必须一致;</li>
* <li>互为镜像的两个属性在获取值,且两者的值皆不同时,必须且仅允许有一个非默认值,该值被优先返回;</li>
* <li>互为镜像的两个属性,在值都为默认值或都不为默认值时,两者的值必须相等;</li>
* </ul>
*/
MIRROR_FOR
,
/**
* <p>表示“原始属性”将作为“关联属性”的别名。
* <ul>
* <li>当“原始属性”为默认值时,获取“关联属性”将返回“关联属性”本身的值;</li>
* <li>当“原始属性”不为默认值时,获取“关联属性”将返回“原始属性”的值;</li>
* </ul>
*/
ALIAS_FOR
,
/**
* <p>表示“原始属性”将强制作为“关联属性”的别名。效果等同于在“原始属性”上添加{@link Alias}注解,
* 任何情况下,获取“关联属性”的值都将直接返回“原始属性”的值
*/
FORCE_ALIAS_FOR
;
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.Annotation
;
/**
* <p>表示基于特定规则聚合,将一组注解聚合而来的注解对象,
* 该注解对象允许根据一定规则“合成”一些跟原始注解属性不一样合成注解。
*
* <p>合成注解一般被用于处理类层级结果中具有直接或间接关联的注解对象,
* 当实例被创建时,会获取到这些注解对象,并使用{@link SynthesizedAnnotationSelector}对类型相同的注解进行过滤,
* 并最终得到类型不重复的有效注解对象。这些有效注解将被包装为{@link SynthesizedAnnotation},
* 然后最终用于“合成”一个{@link SynthesizedAggregateAnnotation}。<br>
* {@link SynthesizedAnnotationSelector}是合成注解生命周期中的第一个钩子,
* 自定义选择器以拦截原始注解被扫描的过程。
*
* <p>当合成注解完成对待合成注解的扫描,并完成了必要属性的加载后,
* 将会按顺序依次调用{@link SynthesizedAnnotationPostProcessor},
* 注解后置处理器允许用于对完成注解的待合成注解进行二次调整,
* 该钩子一般用于根据{@link Link}注解对属性进行调整。<br>
* {@link SynthesizedAnnotationPostProcessor}是合成注解生命周期中的第二个钩子,
* 自定义后置处理器以拦截原始在转为待合成注解后的初始化过程。
*
* <p>合成注解允许通过{@link #synthesize(Class)}合成一个指定的注解对象,
* 该方法返回的注解对象可能是原始的注解对象,也有可能通过动态代理的方式生成,
* 该对象实例的属性不一定来自对象本身,而是来自于经过{@link SynthesizedAnnotationAttributeProcessor}
* 处理后的、用于合成当前实例的全部关联注解的相关属性。<br>
* {@link SynthesizedAnnotationAttributeProcessor}是合成注解生命周期中的第三个钩子,
* 自定义属性处理器以拦截合成注解的取值过程。
*
* @author huangchengxing
* @see AnnotationSynthesizer
* @see SynthesizedAnnotation
* @see SynthesizedAnnotationSelector
* @see SynthesizedAnnotationAttributeProcessor
* @see SynthesizedAnnotationPostProcessor
* @see GenericSynthesizedAggregateAnnotation
*/
public
interface
SynthesizedAggregateAnnotation
extends
AggregateAnnotation
,
Hierarchical
,
AnnotationSynthesizer
,
AnnotationAttributeValueProvider
{
// ================== hierarchical ==================
/**
* 距离{@link #getRoot()}返回值的垂直距离,
* 默认聚合注解即为根对象,因此返回0
*
* @return 距离{@link #getRoot()}返回值的水平距离,
*/
@Override
default
int
getVerticalDistance
()
{
return
0
;
}
/**
* 距离{@link #getRoot()}返回值的水平距离,
* 默认聚合注解即为根对象,因此返回0
*
* @return 距离{@link #getRoot()}返回值的水平距离,
*/
@Override
default
int
getHorizontalDistance
()
{
return
0
;
}
// ================== synthesize ==================
/**
* 获取在聚合中存在的指定注解对象
*
* @param annotationType 注解类型
* @param <T> 注解类型
* @return 注解对象
*/
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotationType
);
/**
* 获取合成注解属性处理器
*
* @return 合成注解属性处理器
*/
SynthesizedAnnotationAttributeProcessor
getAnnotationAttributeProcessor
();
/**
* 获取当前的注解类型
*
* @return 注解类型
*/
@Override
default
Class
<?
extends
Annotation
>
annotationType
()
{
return
this
.
getClass
();
}
/**
* 从聚合中获取指定类型的属性值
*
* @param attributeName 属性名称
* @param attributeType 属性类型
* @return 属性值
*/
@Override
Object
getAttributeValue
(
String
attributeName
,
Class
<?>
attributeType
);
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.collection.CollUtil
;
import
java.lang.annotation.Annotation
;
import
java.util.Map
;
import
java.util.function.UnaryOperator
;
/**
* <p>用于在{@link SynthesizedAggregateAnnotation}中表示一个处于合成状态的注解对象。<br>
* 当对多个合成注解排序时,默认使用{@link #DEFAULT_HIERARCHICAL_COMPARATOR}进行排序,
* 从保证合成注解按{@link #getVerticalDistance()}与{@link #getHorizontalDistance()}的返回值保持有序,
* 从而使得距离根元素更接近的注解对象在被处理是具有更高的优先级。
*
* @author huangchengxing
* @see SynthesizedAggregateAnnotation
*/
public
interface
SynthesizedAnnotation
extends
Annotation
,
Hierarchical
,
AnnotationAttributeValueProvider
{
/**
* 获取被合成的注解对象
*
* @return 注解对象
*/
Annotation
getAnnotation
();
/**
* 获取该合成注解与根对象的垂直距离。
* 默认情况下,该距离即为当前注解与根对象之间相隔的层级数。
*
* @return 合成注解与根对象的垂直距离
*/
@Override
int
getVerticalDistance
();
/**
* 获取该合成注解与根对象的水平距离。
* 默认情况下,该距离即为当前注解与根对象之间相隔的已经被扫描到的注解数。
*
* @return 合成注解与根对象的水平距离
*/
@Override
int
getHorizontalDistance
();
/**
* 注解是否存在该名称相同,且类型一致的属性
*
* @param attributeName 属性名
* @param returnType 返回值类型
* @return 是否存在该属性
*/
boolean
hasAttribute
(
String
attributeName
,
Class
<?>
returnType
);
/**
* 获取该注解的全部属性
*
* @return 注解属性
*/
Map
<
String
,
AnnotationAttribute
>
getAttributes
();
/**
* 设置该注解的全部属性
*
* @param attributes 注解属性
*/
default
void
setAttributes
(
Map
<
String
,
AnnotationAttribute
>
attributes
)
{
if
(
CollUtil
.
isNotEmpty
(
attributes
))
{
attributes
.
forEach
(
this
::
setAttribute
);
}
}
/**
* 设置属性值
*
* @param attributeName 属性名称
* @param attribute 注解属性
*/
void
setAttribute
(
String
attributeName
,
AnnotationAttribute
attribute
);
/**
* 替换属性值
*
* @param attributeName 属性名
* @param operator 替换操作
*/
void
replaceAttribute
(
String
attributeName
,
UnaryOperator
<
AnnotationAttribute
>
operator
);
/**
* 获取属性值
*
* @param attributeName 属性名
* @return 属性值
*/
Object
getAttributeValue
(
String
attributeName
);
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationAttributeProcessor.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.util.Collection
;
/**
* 合成注解属性选择器。用于在{@link SynthesizedAggregateAnnotation}中从指定类型的合成注解里获取到对应的属性值
*
* @author huangchengxing
*/
@FunctionalInterface
public
interface
SynthesizedAnnotationAttributeProcessor
{
/**
* 从一批被合成注解中,获取指定名称与类型的属性值
*
* @param attributeName 属性名称
* @param attributeType 属性类型
* @param synthesizedAnnotations 被合成的注解
* @param <R> 属性类型
* @return 属性值
*/
<
R
>
R
getAttributeValue
(
String
attributeName
,
Class
<
R
>
attributeType
,
Collection
<?
extends
SynthesizedAnnotation
>
synthesizedAnnotations
);
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.comparator.CompareUtil
;
import
java.util.Comparator
;
/**
* <p>被合成注解后置处理器,用于在{@link SynthesizedAggregateAnnotation}加载完所有待合成注解后,
* 再对加载好的{@link SynthesizedAnnotation}进行后置处理。<br>
* 当多个{@link SynthesizedAnnotationPostProcessor}需要一起执行时,将按照{@link #order()}的返回值进行排序,
* 该值更小的处理器将被优先执行。
*
* <p>该接口存在多个实现类,调用者应当保证在任何时候,对一批后置处理器的调用顺序都符合:
* <ul>
* <li>{@link AliasAnnotationPostProcessor};</li>
* <li>{@link MirrorLinkAnnotationPostProcessor};</li>
* <li>{@link AliasLinkAnnotationPostProcessor};</li>
* <li>其他后置处理器;</li>
* </ul>
*
* @author huangchengxing
* @see AliasAnnotationPostProcessor
* @see MirrorLinkAnnotationPostProcessor
* @see AliasLinkAnnotationPostProcessor
*/
public
interface
SynthesizedAnnotationPostProcessor
extends
Comparable
<
SynthesizedAnnotationPostProcessor
>
{
/**
* 属性上带有{@link Alias}的注解对象的后置处理器
*/
AliasAnnotationPostProcessor
ALIAS_ANNOTATION_POST_PROCESSOR
=
new
AliasAnnotationPostProcessor
();
/**
* 属性上带有{@link Link},且与其他注解的属性存在镜像关系的注解对象的后置处理器
*/
MirrorLinkAnnotationPostProcessor
MIRROR_LINK_ANNOTATION_POST_PROCESSOR
=
new
MirrorLinkAnnotationPostProcessor
();
/**
* 属性上带有{@link Link},且与其他注解的属性存在别名关系的注解对象的后置处理器
*/
AliasLinkAnnotationPostProcessor
ALIAS_LINK_ANNOTATION_POST_PROCESSOR
=
new
AliasLinkAnnotationPostProcessor
();
/**
* 在一组后置处理器中被调用的顺序,越小越靠前
*
* @return 排序值
*/
default
int
order
()
{
return
Integer
.
MAX_VALUE
;
}
/**
* 比较两个后置处理器的{@link #order()}返回值
*
* @param o 比较对象
* @return 大小
*/
@Override
default
int
compareTo
(
SynthesizedAnnotationPostProcessor
o
)
{
return
CompareUtil
.
compare
(
this
,
o
,
Comparator
.
comparing
(
SynthesizedAnnotationPostProcessor:
:
order
));
}
/**
* 给定指定被合成注解与其所属的合成注解聚合器实例,经过处理后返回最终
*
* @param synthesizedAnnotation 合成的注解
* @param synthesizer 注解合成器
*/
void
process
(
SynthesizedAnnotation
synthesizedAnnotation
,
AnnotationSynthesizer
synthesizer
);
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationProxy.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.lang.Opt
;
import
cn.hutool.core.text.CharSequenceUtil
;
import
cn.hutool.core.util.ClassUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.ReflectUtil
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.function.BiFunction
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
/**
* 合成注解代理类,用于为{@link SynthesizedAnnotation}生成对应的合成注解代理对象
*
* @author huangchengxing
* @see SynthesizedAnnotation
* @see AnnotationAttributeValueProvider
*/
public
class
SynthesizedAnnotationProxy
implements
InvocationHandler
{
private
final
AnnotationAttributeValueProvider
annotationAttributeValueProvider
;
private
final
SynthesizedAnnotation
annotation
;
private
final
Map
<
String
,
BiFunction
<
Method
,
Object
[],
Object
>>
methods
;
/**
* 创建一个代理注解,生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类。
*
* @param <T> 注解类型
* @param annotationType 注解类型
* @param annotationAttributeValueProvider 注解属性值获取器
* @param annotation 合成注解
* @return 代理注解
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
extends
Annotation
>
T
create
(
Class
<
T
>
annotationType
,
AnnotationAttributeValueProvider
annotationAttributeValueProvider
,
SynthesizedAnnotation
annotation
)
{
if
(
ObjectUtil
.
isNull
(
annotation
))
{
return
null
;
}
final
SynthesizedAnnotationProxy
proxyHandler
=
new
SynthesizedAnnotationProxy
(
annotationAttributeValueProvider
,
annotation
);
if
(
ObjectUtil
.
isNull
(
annotation
))
{
return
null
;
}
return
(
T
)
Proxy
.
newProxyInstance
(
annotationType
.
getClassLoader
(),
new
Class
[]{
annotationType
,
SyntheticProxyAnnotation
.
class
},
proxyHandler
);
}
/**
* 创建一个代理注解,生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类。
*
* @param <T> 注解类型
* @param annotationType 注解类型
* @param annotation 合成注解
* @return 代理注解
*/
public
static
<
T
extends
Annotation
>
T
create
(
Class
<
T
>
annotationType
,
SynthesizedAnnotation
annotation
)
{
return
create
(
annotationType
,
annotation
,
annotation
);
}
/**
* 该类是否为通过{@code SynthesizedAnnotationProxy}生成的代理类
*
* @param annotationType 注解类型
* @return 是否
*/
public
static
boolean
isProxyAnnotation
(
Class
<?>
annotationType
)
{
return
ClassUtil
.
isAssignable
(
SyntheticProxyAnnotation
.
class
,
annotationType
);
}
SynthesizedAnnotationProxy
(
AnnotationAttributeValueProvider
annotationAttributeValueProvider
,
SynthesizedAnnotation
annotation
)
{
Assert
.
notNull
(
annotationAttributeValueProvider
,
"annotationAttributeValueProvider must not null"
);
Assert
.
notNull
(
annotation
,
"annotation must not null"
);
this
.
annotationAttributeValueProvider
=
annotationAttributeValueProvider
;
this
.
annotation
=
annotation
;
this
.
methods
=
new
HashMap
<>(
9
);
loadMethods
();
}
@Override
public
Object
invoke
(
Object
proxy
,
Method
method
,
Object
[]
args
)
throws
Throwable
{
return
Opt
.
ofNullable
(
methods
.
get
(
method
.
getName
()))
.
map
(
m
->
m
.
apply
(
method
,
args
))
.
orElseGet
(()
->
ReflectUtil
.
invoke
(
this
,
method
,
args
));
}
// ========================= 代理方法 =========================
void
loadMethods
()
{
methods
.
put
(
"toString"
,
(
method
,
args
)
->
proxyToString
());
methods
.
put
(
"hashCode"
,
(
method
,
args
)
->
proxyHashCode
());
methods
.
put
(
"getSynthesizedAnnotation"
,
(
method
,
args
)
->
proxyGetSynthesizedAnnotation
());
methods
.
put
(
"getRoot"
,
(
method
,
args
)
->
annotation
.
getRoot
());
methods
.
put
(
"getVerticalDistance"
,
(
method
,
args
)
->
annotation
.
getVerticalDistance
());
methods
.
put
(
"getHorizontalDistance"
,
(
method
,
args
)
->
annotation
.
getHorizontalDistance
());
methods
.
put
(
"hasAttribute"
,
(
method
,
args
)
->
annotation
.
hasAttribute
((
String
)
args
[
0
],
(
Class
<?>)
args
[
1
]));
methods
.
put
(
"getAttributes"
,
(
method
,
args
)
->
annotation
.
getAttributes
());
methods
.
put
(
"setAttribute"
,
(
method
,
args
)
->
{
throw
new
UnsupportedOperationException
(
"proxied annotation can not reset attributes"
);
});
methods
.
put
(
"getAttributeValue"
,
(
method
,
args
)
->
annotation
.
getAttributeValue
((
String
)
args
[
0
]));
methods
.
put
(
"annotationType"
,
(
method
,
args
)
->
annotation
.
annotationType
());
for
(
final
Method
declaredMethod
:
ClassUtil
.
getDeclaredMethods
(
annotation
.
getAnnotation
().
annotationType
()))
{
methods
.
put
(
declaredMethod
.
getName
(),
(
method
,
args
)
->
proxyAttributeValue
(
method
));
}
}
private
String
proxyToString
()
{
final
String
attributes
=
Stream
.
of
(
ClassUtil
.
getDeclaredMethods
(
annotation
.
getAnnotation
().
annotationType
()))
.
filter
(
AnnotationUtil:
:
isAttributeMethod
)
.
map
(
method
->
CharSequenceUtil
.
format
(
"{}={}"
,
method
.
getName
(),
proxyAttributeValue
(
method
))
)
.
collect
(
Collectors
.
joining
(
", "
));
return
CharSequenceUtil
.
format
(
"@{}({})"
,
annotation
.
annotationType
().
getName
(),
attributes
);
}
private
int
proxyHashCode
()
{
return
Objects
.
hash
(
annotationAttributeValueProvider
,
annotation
);
}
private
Object
proxyGetSynthesizedAnnotation
()
{
return
annotation
;
}
private
Object
proxyAttributeValue
(
Method
attributeMethod
)
{
return
annotationAttributeValueProvider
.
getAttributeValue
(
attributeMethod
.
getName
(),
attributeMethod
.
getReturnType
());
}
/**
* 通过代理类生成的合成注解
*
* @author huangchengxing
*/
interface
SyntheticProxyAnnotation
extends
SynthesizedAnnotation
{
/**
* 获取该代理注解对应的已合成注解
*
* @return 理注解对应的已合成注解
*/
SynthesizedAnnotation
getSynthesizedAnnotation
();
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationSelector.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
/**
* 注解选择器,指定两个注解,选择其中一个返回。<br>
* 该接口用于在{@link SynthesizedAggregateAnnotation}中用于从一批相同的注解对象中筛选最终用于合成注解对象。
*
* @author huangchengxing
*/
@FunctionalInterface
public
interface
SynthesizedAnnotationSelector
{
/**
* 返回距离根对象更近的注解,当距离一样时优先返回旧注解
*/
SynthesizedAnnotationSelector
NEAREST_AND_OLDEST_PRIORITY
=
new
NearestAndOldestPrioritySelector
();
/**
* 返回距离根对象更近的注解,当距离一样时优先返回新注解
*/
SynthesizedAnnotationSelector
NEAREST_AND_NEWEST_PRIORITY
=
new
NearestAndNewestPrioritySelector
();
/**
* 返回距离根对象更远的注解,当距离一样时优先返回旧注解
*/
SynthesizedAnnotationSelector
FARTHEST_AND_OLDEST_PRIORITY
=
new
FarthestAndOldestPrioritySelector
();
/**
* 返回距离根对象更远的注解,当距离一样时优先返回新注解
*/
SynthesizedAnnotationSelector
FARTHEST_AND_NEWEST_PRIORITY
=
new
FarthestAndNewestPrioritySelector
();
/**
* 比较两个被合成的注解,选择其中的一个并返回
*
* @param <T> 复合注解类型
* @param oldAnnotation 已存在的注解,该参数不允许为空
* @param newAnnotation 新获取的注解,该参数不允许为空
* @return 被合成的注解
*/
<
T
extends
SynthesizedAnnotation
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
);
/**
* 返回距离根对象更近的注解,当距离一样时优先返回旧注解
*/
class
NearestAndOldestPrioritySelector
implements
SynthesizedAnnotationSelector
{
@Override
public
<
T
extends
SynthesizedAnnotation
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
Hierarchical
.
Selector
.
NEAREST_AND_OLDEST_PRIORITY
.
choose
(
oldAnnotation
,
newAnnotation
);
}
}
/**
* 返回距离根对象更近的注解,当距离一样时优先返回新注解
*/
class
NearestAndNewestPrioritySelector
implements
SynthesizedAnnotationSelector
{
@Override
public
<
T
extends
SynthesizedAnnotation
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
Hierarchical
.
Selector
.
NEAREST_AND_NEWEST_PRIORITY
.
choose
(
oldAnnotation
,
newAnnotation
);
}
}
/**
* 返回距离根对象更远的注解,当距离一样时优先返回旧注解
*/
class
FarthestAndOldestPrioritySelector
implements
SynthesizedAnnotationSelector
{
@Override
public
<
T
extends
SynthesizedAnnotation
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
Hierarchical
.
Selector
.
FARTHEST_AND_OLDEST_PRIORITY
.
choose
(
oldAnnotation
,
newAnnotation
);
}
}
/**
* 返回距离根对象更远的注解,当距离一样时优先返回新注解
*/
class
FarthestAndNewestPrioritySelector
implements
SynthesizedAnnotationSelector
{
@Override
public
<
T
extends
SynthesizedAnnotation
>
T
choose
(
T
oldAnnotation
,
T
newAnnotation
)
{
return
Hierarchical
.
Selector
.
FARTHEST_AND_NEWEST_PRIORITY
.
choose
(
oldAnnotation
,
newAnnotation
);
}
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/WrappedAnnotationAttribute.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Method
;
import
java.util.Collection
;
/**
* <p>表示一个被包装过的{@link AnnotationAttribute},
* 该实例中的一些方法可能会被代理到另一个注解属性对象中,
* 从而使得通过原始的注解属性的方法获取到另一注解属性的值。<br>
* 除了{@link #getValue()}以外,其他方法的返回值应当尽可能与{@link #getOriginal()}
* 返回的{@link AnnotationAttribute}对象的方法返回值一致。
*
* <p>当包装类被包装了多层后,则规则生效优先级按包装的先后顺序倒序排序,
* 比如a、b互为镜像,此时a、b两属性应当都被{@link MirroredAnnotationAttribute}包装,
* 若再指定c为a的别名字段,则c、a、b都要在原基础上再次包装一层{@link AliasedAnnotationAttribute}。<br>
* 此时a、b同时被包装了两层,则执行时,优先执行{@link AliasedAnnotationAttribute}的逻辑,
* 当该规则不生效时,比如c只有默认值,此时上一次的{@link MirroredAnnotationAttribute}的逻辑才会生效。
*
* <p>被包装的{@link AnnotationAttribute}实际结构为一颗二叉树,
* 当包装类再次被包装时,实际上等于又添加了一个新的根节点,
* 此时需要同时更新树的全部关联叶子节点。
*
* @author huangchengxing
* @see AnnotationAttribute
* @see ForceAliasedAnnotationAttribute
* @see AliasedAnnotationAttribute
* @see MirroredAnnotationAttribute
*/
public
interface
WrappedAnnotationAttribute
extends
AnnotationAttribute
{
// =========================== 新增方法 ===========================
/**
* 获取被包装的{@link AnnotationAttribute}对象,该对象也可能是{@link AnnotationAttribute}
*
* @return 被包装的{@link AnnotationAttribute}对象
*/
AnnotationAttribute
getOriginal
();
/**
* 获取最初的被包装的{@link AnnotationAttribute}
*
* @return 最初的被包装的{@link AnnotationAttribute}
*/
AnnotationAttribute
getNonWrappedOriginal
();
/**
* 获取包装{@link #getOriginal()}的{@link AnnotationAttribute}对象,该对象也可能是{@link AnnotationAttribute}
*
* @return 包装对象
*/
AnnotationAttribute
getLinked
();
/**
* 遍历以当前实例为根节点的树结构,获取所有未被包装的属性
*
* @return 叶子节点
*/
Collection
<
AnnotationAttribute
>
getAllLinkedNonWrappedAttributes
();
// =========================== 代理实现 ===========================
/**
* 获取注解对象
*
* @return 注解对象
*/
@Override
default
Annotation
getAnnotation
()
{
return
getOriginal
().
getAnnotation
();
}
/**
* 获取注解属性对应的方法
*
* @return 注解属性对应的方法
*/
@Override
default
Method
getAttribute
()
{
return
getOriginal
().
getAttribute
();
}
/**
* 该注解属性的值是否等于默认值 <br>
* 默认仅当{@link #getOriginal()}与{@link #getLinked()}返回的注解属性
* 都为默认值时,才返回{@code true}
*
* @return 该注解属性的值是否等于默认值
*/
@Override
boolean
isValueEquivalentToDefaultValue
();
/**
* 获取属性类型
*
* @return 属性类型
*/
@Override
default
Class
<?>
getAttributeType
()
{
return
getOriginal
().
getAttributeType
();
}
/**
* 获取属性上的注解
*
* @param annotationType 注解类型
* @return 注解对象
*/
@Override
default
<
T
extends
Annotation
>
T
getAnnotation
(
Class
<
T
>
annotationType
)
{
return
getOriginal
().
getAnnotation
(
annotationType
);
}
/**
* 当前注解属性是否已经被{@link WrappedAnnotationAttribute}包装
*
* @return boolean
*/
@Override
default
boolean
isWrapped
()
{
return
true
;
}
}
hutool-core/src/main/java/cn/hutool/core/annotation/package-info.java
0 → 100644
View file @
45cda665
/**
* 注解包,提供增强型注解和注解工具类
*
* @author looly
*
*/
package
cn.hutool.core.annotation
;
\ No newline at end of file
hutool-core/src/main/java/cn/hutool/core/annotation/scanner/AbstractTypeAnnotationScanner.java
0 → 100644
View file @
45cda665
package
cn.hutool.core.annotation.scanner
;
import
cn.hutool.core.annotation.AnnotationUtil
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.util.ArrayUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.AnnotatedElement
;
import
java.lang.reflect.Proxy
;
import
java.util.*
;
import
java.util.function.BiConsumer
;
import
java.util.function.Predicate
;
import
java.util.function.UnaryOperator
;
/**
* 为需要从类的层级结构中获取注解的{@link AnnotationScanner}提供基本实现
*
* @author huangchengxing
*/
public
abstract
class
AbstractTypeAnnotationScanner
<
T
extends
AbstractTypeAnnotationScanner
<
T
>>
implements
AnnotationScanner
{
/**
* 是否允许扫描父类
*/
private
boolean
includeSuperClass
;
/**
* 是否允许扫描父接口
*/
private
boolean
includeInterfaces
;
/**
* 过滤器,若类型无法通过该过滤器,则该类型及其树结构将直接不被查找
*/
private
Predicate
<
Class
<?>>
filter
;
/**
* 排除的类型,以上类型及其树结构将直接不被查找
*/
private
final
Set
<
Class
<?>>
excludeTypes
;
/**
* 转换器
*/
private
final
List
<
UnaryOperator
<
Class
<?>>>
converters
;
/**
* 是否有转换器
*/
private
boolean
hasConverters
;
/**
* 当前实例
*/
private
final
T
typedThis
;
/**
* 构造一个类注解扫描器
*
* @param includeSuperClass 是否允许扫描父类
* @param includeInterfaces 是否允许扫描父接口
* @param filter 过滤器
* @param excludeTypes 不包含的类型
*/
@SuppressWarnings
(
"unchecked"
)
protected
AbstractTypeAnnotationScanner
(
boolean
includeSuperClass
,
boolean
includeInterfaces
,
Predicate
<
Class
<?>>
filter
,
Set
<
Class
<?>>
excludeTypes
)
{
Assert
.
notNull
(
filter
,
"filter must not null"
);
Assert
.
notNull
(
excludeTypes
,
"excludeTypes must not null"
);
this
.
includeSuperClass
=
includeSuperClass
;
this
.
includeInterfaces
=
includeInterfaces
;
this
.
filter
=
filter
;
this
.
excludeTypes
=
excludeTypes
;
this
.
converters
=
new
ArrayList
<>();
this
.
typedThis
=
(
T
)
this
;
}
/**
* 是否允许扫描父类
*
* @return 是否允许扫描父类
*/
public
boolean
isIncludeSuperClass
()
{
return
includeSuperClass
;
}
/**
* 是否允许扫描父接口
*
* @return 是否允许扫描父接口
*/
public
boolean
isIncludeInterfaces
()
{
return
includeInterfaces
;
}
/**
* 设置过滤器,若类型无法通过该过滤器,则该类型及其树结构将直接不被查找
*
* @param filter 过滤器
* @return 当前实例
*/
public
T
setFilter
(
Predicate
<
Class
<?>>
filter
)
{
Assert
.
notNull
(
filter
,
"filter must not null"
);
this
.
filter
=
filter
;
return
typedThis
;
}
/**
* 添加不扫描的类型,该类型及其树结构将直接不被查找
*
* @param excludeTypes 不扫描的类型
* @return 当前实例
*/
public
T
addExcludeTypes
(
Class
<?>...
excludeTypes
)
{
CollUtil
.
addAll
(
this
.
excludeTypes
,
excludeTypes
);
return
typedThis
;
}
/**
* 添加转换器
*
* @param converter 转换器
* @return 当前实例
* @see JdkProxyClassConverter
*/
public
T
addConverters
(
UnaryOperator
<
Class
<?>>
converter
)
{
Assert
.
notNull
(
converter
,
"converter must not null"
);
this
.
converters
.
add
(
converter
);
if
(!
this
.
hasConverters
)
{
this
.
hasConverters
=
CollUtil
.
isNotEmpty
(
this
.
converters
);
}
return
typedThis
;
}
/**
* 是否允许扫描父类
*
* @param includeSuperClass 是否
* @return 当前实例
*/
protected
T
setIncludeSuperClass
(
boolean
includeSuperClass
)
{
this
.
includeSuperClass
=
includeSuperClass
;
return
typedThis
;
}
/**
* 是否允许扫描父接口
*
* @param includeInterfaces 是否
* @return 当前实例
*/
protected
T
setIncludeInterfaces
(
boolean
includeInterfaces
)
{
this
.
includeInterfaces
=
includeInterfaces
;
return
typedThis
;
}
/**
* 则根据广度优先递归扫描类的层级结构,并对层级结构中类/接口声明的层级索引和它们声明的注解对象进行处理
*
* @param consumer 对获取到的注解和注解对应的层级索引的处理
* @param annotatedEle 注解元素
* @param filter 注解过滤器,无法通过过滤器的注解不会被处理。该参数允许为空。
*/
@Override
public
void
scan
(
BiConsumer
<
Integer
,
Annotation
>
consumer
,
AnnotatedElement
annotatedEle
,
Predicate
<
Annotation
>
filter
)
{
filter
=
ObjectUtil
.
defaultIfNull
(
filter
,
a
->
annotation
->
true
);
final
Class
<?>
sourceClass
=
getClassFormAnnotatedElement
(
annotatedEle
);
final
Deque
<
List
<
Class
<?>>>
classDeque
=
CollUtil
.
newLinkedList
(
CollUtil
.
newArrayList
(
sourceClass
));
final
Set
<
Class
<?>>
accessedTypes
=
new
LinkedHashSet
<>();
int
index
=
0
;
while
(!
classDeque
.
isEmpty
())
{
final
List
<
Class
<?>>
currClassQueue
=
classDeque
.
removeFirst
();
final
List
<
Class
<?>>
nextClassQueue
=
new
ArrayList
<>();
for
(
Class
<?>
targetClass
:
currClassQueue
)
{
targetClass
=
convert
(
targetClass
);
// 过滤不需要处理的类
if
(
isNotNeedProcess
(
accessedTypes
,
targetClass
))
{
continue
;
}
accessedTypes
.
add
(
targetClass
);
// 扫描父类
scanSuperClassIfNecessary
(
nextClassQueue
,
targetClass
);
// 扫描接口
scanInterfaceIfNecessary
(
nextClassQueue
,
targetClass
);
// 处理层级索引和注解
final
Annotation
[]
targetAnnotations
=
getAnnotationsFromTargetClass
(
annotatedEle
,
index
,
targetClass
);
for
(
final
Annotation
annotation
:
targetAnnotations
)
{
if
(
AnnotationUtil
.
isNotJdkMateAnnotation
(
annotation
.
annotationType
())
&&
filter
.
test
(
annotation
))
{
consumer
.
accept
(
index
,
annotation
);
}
}
index
++;
}
if
(
CollUtil
.
isNotEmpty
(
nextClassQueue
))
{
classDeque
.
addLast
(
nextClassQueue
);
}
}
}
/**
* 从要搜索的注解元素上获得要递归的类型
*
* @param annotatedElement 注解元素
* @return 要递归的类型
*/
protected
abstract
Class
<?>
getClassFormAnnotatedElement
(
AnnotatedElement
annotatedElement
);
/**
* 从类上获取最终所需的目标注解
*
* @param source 最初的注解元素
* @param index 类的层级索引
* @param targetClass 类
* @return 最终所需的目标注解
*/
protected
abstract
Annotation
[]
getAnnotationsFromTargetClass
(
AnnotatedElement
source
,
int
index
,
Class
<?>
targetClass
);
/**
* 当前类是否不需要处理
*
* @param accessedTypes 访问类型
* @param targetClass 目标类型
* @return 是否不需要处理
*/
protected
boolean
isNotNeedProcess
(
Set
<
Class
<?>>
accessedTypes
,
Class
<?>
targetClass
)
{
return
ObjectUtil
.
isNull
(
targetClass
)
||
accessedTypes
.
contains
(
targetClass
)
||
excludeTypes
.
contains
(
targetClass
)
||
filter
.
negate
().
test
(
targetClass
);
}
/**
* 若{@link #includeInterfaces}为{@code true},则将目标类的父接口也添加到nextClasses
*
* @param nextClasses 下一个类集合
* @param targetClass 目标类型
*/
protected
void
scanInterfaceIfNecessary
(
List
<
Class
<?>>
nextClasses
,
Class
<?>
targetClass
)
{
if
(
includeInterfaces
)
{
final
Class
<?>[]
interfaces
=
targetClass
.
getInterfaces
();
if
(
ArrayUtil
.
isNotEmpty
(
interfaces
))
{
CollUtil
.
addAll
(
nextClasses
,
interfaces
);
}
}
}
/**
* 若{@link #includeSuperClass}为{@code true},则将目标类的父类也添加到nextClasses
*
* @param nextClassQueue 下一个类队列
* @param targetClass 目标类型
*/
protected
void
scanSuperClassIfNecessary
(
List
<
Class
<?>>
nextClassQueue
,
Class
<?>
targetClass
)
{
if
(
includeSuperClass
)
{
final
Class
<?>
superClass
=
targetClass
.
getSuperclass
();
if
(!
ObjectUtil
.
equals
(
superClass
,
Object
.
class
)
&&
ObjectUtil
.
isNotNull
(
superClass
))
{
nextClassQueue
.
add
(
superClass
);
}
}
}
/**
* 若存在转换器,则使用转换器对目标类进行转换
*
* @param target 目标类
* @return 转换后的类
*/
protected
Class
<?>
convert
(
Class
<?>
target
)
{
if
(
hasConverters
)
{
for
(
final
UnaryOperator
<
Class
<?>>
converter
:
converters
)
{
target
=
converter
.
apply
(
target
);
}
}
return
target
;
}
/**
* 若类型为jdk代理类,则尝试转换为原始被代理类
*/
public
static
class
JdkProxyClassConverter
implements
UnaryOperator
<
Class
<?>>
{
@Override
public
Class
<?>
apply
(
Class
<?>
sourceClass
)
{
return
Proxy
.
isProxyClass
(
sourceClass
)
?
apply
(
sourceClass
.
getSuperclass
())
:
sourceClass
;
}
}
}
Prev
1
…
4
5
6
7
8
9
10
11
12
…
19
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment