25
25
import javax .interceptor .AroundTimeout ;
26
26
import java .lang .annotation .Annotation ;
27
27
import java .lang .reflect .Method ;
28
- import java .util .HashMap ;
29
- import java .util .Map ;
30
- import java .util .Set ;
28
+ import java .util .*;
29
+ import java .util .function .Consumer ;
31
30
import java .util .function .Predicate ;
32
31
33
32
import static java .lang .String .format ;
34
- import static org . geektimes . commons . collection . util .CollectionUtils . asSet ;
33
+ import static java . util .Collections . unmodifiableCollection ;
35
34
import static org .geektimes .commons .lang .util .AnnotationUtils .getAllDeclaredAnnotations ;
36
- import static org .geektimes .commons .reflect .util .MethodUtils . getAllDeclaredMethods ;
35
+ import static org .geektimes .commons .reflect .util .ClassUtils . getAllClasses ;
37
36
import static org .geektimes .interceptor .util .InterceptorUtils .validatorInterceptorClass ;
38
37
39
38
/**
@@ -48,59 +47,80 @@ public class InterceptorInfo {
48
47
49
48
private final Class <?> interceptorClass ;
50
49
51
- private final Method aroundInvokeMethod ;
50
+ /**
51
+ * If an interceptor class declared using interceptor bindings has superclasses,
52
+ * interceptor methods declared in the interceptor class’s superclasses are
53
+ * invoked before the interceptor method declared in the interceptor class itself,
54
+ * most general superclass first.
55
+ */
56
+ private final Collection <Method > aroundInvokeMethods ;
52
57
53
- private final Method aroundTimeoutMethod ;
58
+ private final Collection < Method > aroundTimeoutMethods ;
54
59
55
- private final Method aroundConstructMethod ;
60
+ private final Collection < Method > aroundConstructMethods ;
56
61
57
- private final Method postConstructMethod ;
62
+ private final Collection < Method > postConstructMethods ;
58
63
59
- private final Method preDestroyMethod ;
64
+ private final Collection < Method > preDestroyMethods ;
60
65
61
66
private final InterceptorBindings interceptorBindings ;
62
67
63
68
public InterceptorInfo (Class <?> interceptorClass ) {
64
69
validatorInterceptorClass (interceptorClass );
65
70
this .interceptorManager = InterceptorManager .getInstance (interceptorClass .getClassLoader ());
66
71
this .interceptorClass = interceptorClass ;
67
- Map < Class <? extends Annotation >, Method > interceptionMethods = resolveInterceptionMethods ();
68
- this .aroundInvokeMethod = interceptionMethods . remove ( AroundInvoke . class );
69
- this .aroundTimeoutMethod = interceptionMethods . remove ( AroundTimeout . class );
70
- this .aroundConstructMethod = interceptionMethods . remove ( AroundConstruct . class );
71
- this .postConstructMethod = interceptionMethods . remove ( PostConstruct . class );
72
- this . preDestroyMethod = interceptionMethods . remove ( PreDestroy . class );
72
+ this . aroundInvokeMethods = new LinkedList <> ();
73
+ this .aroundTimeoutMethods = new LinkedList <>( );
74
+ this .aroundConstructMethods = new LinkedList <>( );
75
+ this .postConstructMethods = new LinkedList <>( );
76
+ this .preDestroyMethods = new LinkedList <>( );
77
+ resolveInterceptionMethods ( );
73
78
this .interceptorBindings = resolveInterceptorBindings ();
74
79
}
75
80
76
- private Map <Class <? extends Annotation >, Method > resolveInterceptionMethods () throws IllegalStateException {
77
- Set <Method > methods = getAllDeclaredMethods (interceptorClass , method -> !Object .class .equals (method .getDeclaringClass ()));
78
- Map <Class <? extends Annotation >, Method > interceptionMethods = new HashMap <>();
81
+ private void resolveInterceptionMethods () throws IllegalStateException {
82
+ Set <Class <?>> allClasses = getAllClasses (interceptorClass , true , t -> !Object .class .equals (t ));
79
83
80
- for (Method method : methods ) {
81
- resolveInterceptionMethod (method , AroundInvoke .class , InterceptorUtils ::isAroundInvokeMethod , interceptionMethods );
82
- resolveInterceptionMethod (method , AroundTimeout .class , InterceptorUtils ::isAroundTimeoutMethod , interceptionMethods );
83
- resolveInterceptionMethod (method , AroundConstruct .class , InterceptorUtils ::isAroundConstructMethod , interceptionMethods );
84
- resolveInterceptionMethod (method , PostConstruct .class , InterceptorUtils ::isPostConstructMethod , interceptionMethods );
85
- resolveInterceptionMethod (method , PreDestroy .class , InterceptorUtils ::isPreDestroyMethod , interceptionMethods );
84
+ for (Class <?> declaringClass : allClasses ) {
85
+ Map <Class <? extends Annotation >, Method > interceptionMethods = new HashMap <>();
86
+ for (Method method : declaringClass .getDeclaredMethods ()) {
87
+ resolveInterceptionMethod (method , AroundInvoke .class , InterceptorUtils ::isAroundInvokeMethod ,
88
+ interceptionMethods , aroundInvokeMethods ::add );
89
+
90
+ resolveInterceptionMethod (method , AroundTimeout .class , InterceptorUtils ::isAroundTimeoutMethod ,
91
+ interceptionMethods , aroundTimeoutMethods ::add );
92
+
93
+ resolveInterceptionMethod (method , AroundConstruct .class , InterceptorUtils ::isAroundConstructMethod ,
94
+ interceptionMethods , aroundConstructMethods ::add );
95
+
96
+ resolveInterceptionMethod (method , PostConstruct .class , InterceptorUtils ::isPostConstructMethod ,
97
+ interceptionMethods , postConstructMethods ::add );
98
+
99
+ resolveInterceptionMethod (method , PreDestroy .class , InterceptorUtils ::isPreDestroyMethod ,
100
+ interceptionMethods , preDestroyMethods ::add );
101
+ }
102
+ interceptionMethods .clear ();
86
103
}
87
104
88
- return interceptionMethods ;
89
105
}
90
106
91
- private void resolveInterceptionMethod (Method method , Class <? extends Annotation > annotationType ,
107
+ private void resolveInterceptionMethod (Method method ,
108
+ Class <? extends Annotation > annotationType ,
92
109
Predicate <Method > isInterceptionMethod ,
93
- Map <Class <? extends Annotation >, Method > interceptionMethods ) {
110
+ Map <Class <? extends Annotation >, Method > interceptionMethods ,
111
+ Consumer <Method > interceptionMethodConsumer ) {
94
112
if (isInterceptionMethod .test (method )) {
95
- if (interceptionMethods .putIfAbsent (annotationType , method ) != null ) {
96
- throw interceptionMethodDefinitionException (annotationType );
113
+ if (interceptionMethods .putIfAbsent (annotationType , method ) == null ) {
114
+ interceptionMethodConsumer .accept (method );
115
+ } else {
116
+ throw interceptionMethodDefinitionException (method , annotationType );
97
117
}
98
118
}
99
119
}
100
120
101
- private IllegalStateException interceptionMethodDefinitionException (Class <? extends Annotation > annotationType ) {
102
- throw new IllegalStateException (format ("There is only one @%s method is declared in the interceptor class[%s]" ,
103
- annotationType .getName (), interceptorClass .getName ()));
121
+ private IllegalStateException interceptionMethodDefinitionException (Method method , Class <? extends Annotation > annotationType ) {
122
+ throw new IllegalStateException (format ("There is only one @%s method[%s] is declared in the interceptor class[%s]" ,
123
+ annotationType .getName (), method . toString (), method . getDeclaringClass () .getName ()));
104
124
}
105
125
106
126
private InterceptorBindings resolveInterceptorBindings () {
@@ -111,27 +131,27 @@ public Class<?> getInterceptorClass() {
111
131
return interceptorClass ;
112
132
}
113
133
114
- public Method getAroundInvokeMethod () {
115
- return aroundInvokeMethod ;
134
+ Collection < Method > getAroundInvokeMethods () {
135
+ return aroundInvokeMethods ;
116
136
}
117
137
118
- public Method getAroundTimeoutMethod () {
119
- return aroundTimeoutMethod ;
138
+ Collection < Method > getAroundTimeoutMethods () {
139
+ return aroundTimeoutMethods ;
120
140
}
121
141
122
- public Method getAroundConstructMethod () {
123
- return aroundConstructMethod ;
142
+ Collection < Method > getAroundConstructMethods () {
143
+ return aroundConstructMethods ;
124
144
}
125
145
126
- public Method getPostConstructMethod () {
127
- return postConstructMethod ;
146
+ Collection < Method > getPostConstructMethods () {
147
+ return postConstructMethods ;
128
148
}
129
149
130
- public Method getPreDestroyMethod () {
131
- return preDestroyMethod ;
150
+ Collection < Method > getPreDestroyMethods () {
151
+ return preDestroyMethods ;
132
152
}
133
153
134
- public InterceptorBindings getInterceptorBindings () {
154
+ InterceptorBindings getInterceptorBindings () {
135
155
return interceptorBindings ;
136
156
}
137
157
0 commit comments