1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.aop.aspectj;
18
19 import java.lang.reflect.Method;
20
21 import org.aspectj.lang.ProceedingJoinPoint;
22 import org.junit.Before;
23 import org.junit.Test;
24
25 import org.springframework.aop.MethodBeforeAdvice;
26 import org.springframework.beans.factory.BeanNameAware;
27 import org.springframework.context.support.ClassPathXmlApplicationContext;
28 import org.springframework.core.Ordered;
29 import org.springframework.tests.sample.beans.ITestBean;
30
31 import static org.junit.Assert.*;
32
33
34
35
36
37 public final class AspectAndAdvicePrecedenceTests {
38
39 private PrecedenceTestAspect highPrecedenceAspect;
40
41 private PrecedenceTestAspect lowPrecedenceAspect;
42
43 private SimpleSpringBeforeAdvice highPrecedenceSpringAdvice;
44
45 private SimpleSpringBeforeAdvice lowPrecedenceSpringAdvice;
46
47 private ITestBean testBean;
48
49
50 @Before
51 public void setUp() {
52 ClassPathXmlApplicationContext ctx =
53 new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
54 highPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("highPrecedenceAspect");
55 lowPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("lowPrecedenceAspect");
56 highPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("highPrecedenceSpringAdvice");
57 lowPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("lowPrecedenceSpringAdvice");
58 testBean = (ITestBean) ctx.getBean("testBean");
59 }
60
61
62
63 @Test
64 public void testAdviceOrder() {
65 PrecedenceTestAspect.Collaborator collaborator = new PrecedenceVerifyingCollaborator();
66 this.highPrecedenceAspect.setCollaborator(collaborator);
67 this.lowPrecedenceAspect.setCollaborator(collaborator);
68 this.highPrecedenceSpringAdvice.setCollaborator(collaborator);
69 this.lowPrecedenceSpringAdvice.setCollaborator(collaborator);
70 this.testBean.getAge();
71 }
72
73
74 private static class PrecedenceVerifyingCollaborator implements PrecedenceTestAspect.Collaborator {
75
76 private static final String[] EXPECTED = {
77
78
79 "beforeAdviceOne(highPrecedenceAspect)",
80 "beforeAdviceTwo(highPrecedenceAspect)",
81 "aroundAdviceOne(highPrecedenceAspect)",
82 "aroundAdviceTwo(highPrecedenceAspect)",
83 "beforeAdviceOne(highPrecedenceSpringAdvice)",
84 "beforeAdviceOne(lowPrecedenceSpringAdvice)",
85 "beforeAdviceOne(lowPrecedenceAspect)",
86 "beforeAdviceTwo(lowPrecedenceAspect)",
87 "aroundAdviceOne(lowPrecedenceAspect)",
88 "aroundAdviceTwo(lowPrecedenceAspect)",
89 "aroundAdviceTwo(lowPrecedenceAspect)",
90 "aroundAdviceOne(lowPrecedenceAspect)",
91 "afterAdviceOne(lowPrecedenceAspect)",
92 "afterAdviceTwo(lowPrecedenceAspect)",
93 "aroundAdviceTwo(highPrecedenceAspect)",
94 "aroundAdviceOne(highPrecedenceAspect)",
95 "afterAdviceOne(highPrecedenceAspect)",
96 "afterAdviceTwo(highPrecedenceAspect)"
97 };
98
99 private int adviceInvocationNumber = 0;
100
101 private void checkAdvice(String whatJustHappened) {
102
103 if (adviceInvocationNumber > (EXPECTED.length - 1)) {
104 fail("Too many advice invocations, expecting " + EXPECTED.length
105 + " but had " + adviceInvocationNumber);
106 }
107 String expecting = EXPECTED[adviceInvocationNumber++];
108 if (!whatJustHappened.equals(expecting)) {
109 fail("Expecting '" + expecting + "' on advice invocation " + adviceInvocationNumber +
110 " but got '" + whatJustHappened + "'");
111 }
112 }
113
114 @Override
115 public void beforeAdviceOne(String beanName) {
116 checkAdvice("beforeAdviceOne(" + beanName + ")");
117 }
118
119 @Override
120 public void beforeAdviceTwo(String beanName) {
121 checkAdvice("beforeAdviceTwo(" + beanName + ")");
122 }
123
124 @Override
125 public void aroundAdviceOne(String beanName) {
126 checkAdvice("aroundAdviceOne(" + beanName + ")");
127 }
128
129 @Override
130 public void aroundAdviceTwo(String beanName) {
131 checkAdvice("aroundAdviceTwo(" + beanName + ")");
132 }
133
134 @Override
135 public void afterAdviceOne(String beanName) {
136 checkAdvice("afterAdviceOne(" + beanName + ")");
137 }
138
139 @Override
140 public void afterAdviceTwo(String beanName) {
141 checkAdvice("afterAdviceTwo(" + beanName + ")");
142 }
143 }
144
145 }
146
147
148 class PrecedenceTestAspect implements BeanNameAware, Ordered {
149
150 private String name;
151
152 private int order = Ordered.LOWEST_PRECEDENCE;
153
154 private Collaborator collaborator;
155
156
157 @Override
158 public void setBeanName(String name) {
159 this.name = name;
160 }
161
162 public void setOrder(int order) {
163 this.order = order;
164 }
165
166 @Override
167 public int getOrder() {
168 return order;
169 }
170
171 public void setCollaborator(Collaborator collaborator) {
172 this.collaborator = collaborator;
173 }
174
175 public void beforeAdviceOne() {
176 this.collaborator.beforeAdviceOne(this.name);
177 }
178
179 public void beforeAdviceTwo() {
180 this.collaborator.beforeAdviceTwo(this.name);
181 }
182
183 public int aroundAdviceOne(ProceedingJoinPoint pjp) {
184 int ret = -1;
185 this.collaborator.aroundAdviceOne(this.name);
186 try {
187 ret = ((Integer)pjp.proceed()).intValue();
188 }
189 catch(Throwable t) { throw new RuntimeException(t); }
190 this.collaborator.aroundAdviceOne(this.name);
191 return ret;
192 }
193
194 public int aroundAdviceTwo(ProceedingJoinPoint pjp) {
195 int ret = -1;
196 this.collaborator.aroundAdviceTwo(this.name);
197 try {
198 ret = ((Integer)pjp.proceed()).intValue();
199 }
200 catch(Throwable t) {throw new RuntimeException(t);}
201 this.collaborator.aroundAdviceTwo(this.name);
202 return ret;
203 }
204
205 public void afterAdviceOne() {
206 this.collaborator.afterAdviceOne(this.name);
207 }
208
209 public void afterAdviceTwo() {
210 this.collaborator.afterAdviceTwo(this.name);
211 }
212
213
214 public interface Collaborator {
215
216 void beforeAdviceOne(String beanName);
217 void beforeAdviceTwo(String beanName);
218 void aroundAdviceOne(String beanName);
219 void aroundAdviceTwo(String beanName);
220 void afterAdviceOne(String beanName);
221 void afterAdviceTwo(String beanName);
222 }
223
224 }
225
226
227 class SimpleSpringBeforeAdvice implements MethodBeforeAdvice, BeanNameAware {
228
229 private PrecedenceTestAspect.Collaborator collaborator;
230 private String name;
231
232
233
234
235 @Override
236 public void before(Method method, Object[] args, Object target)
237 throws Throwable {
238 this.collaborator.beforeAdviceOne(this.name);
239 }
240
241 public void setCollaborator(PrecedenceTestAspect.Collaborator collaborator) {
242 this.collaborator = collaborator;
243 }
244
245
246
247
248 @Override
249 public void setBeanName(String name) {
250 this.name = name;
251 }
252
253 }