1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.aop.aspectj.annotation;
17
18 import java.io.FileNotFoundException;
19 import java.lang.annotation.Retention;
20 import java.lang.annotation.RetentionPolicy;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.UndeclaredThrowableException;
23 import java.rmi.RemoteException;
24 import java.util.Collections;
25 import java.util.LinkedList;
26 import java.util.List;
27
28 import org.aspectj.lang.JoinPoint;
29 import org.aspectj.lang.ProceedingJoinPoint;
30 import org.aspectj.lang.annotation.After;
31 import org.aspectj.lang.annotation.AfterReturning;
32 import org.aspectj.lang.annotation.AfterThrowing;
33 import org.aspectj.lang.annotation.Around;
34 import org.aspectj.lang.annotation.Aspect;
35 import org.aspectj.lang.annotation.Before;
36 import org.aspectj.lang.annotation.DeclareParents;
37 import org.aspectj.lang.annotation.DeclarePrecedence;
38 import org.aspectj.lang.annotation.Pointcut;
39 import org.aspectj.lang.reflect.MethodSignature;
40 import org.junit.Ignore;
41 import org.junit.Test;
42 import test.aop.DefaultLockable;
43 import test.aop.Lockable;
44 import test.aop.PerTargetAspect;
45 import test.aop.TwoAdviceAspect;
46
47 import org.springframework.aop.Advisor;
48 import org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor;
49 import org.springframework.aop.framework.Advised;
50 import org.springframework.aop.framework.AopConfigException;
51 import org.springframework.aop.framework.ProxyFactory;
52 import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
53 import org.springframework.aop.support.AopUtils;
54 import org.springframework.core.OrderComparator;
55 import org.springframework.core.Ordered;
56 import org.springframework.core.annotation.Order;
57 import org.springframework.tests.sample.beans.ITestBean;
58 import org.springframework.tests.sample.beans.TestBean;
59 import org.springframework.util.ObjectUtils;
60
61 import static org.hamcrest.Matchers.*;
62 import static org.junit.Assert.*;
63
64
65
66
67
68
69
70
71
72 public abstract class AbstractAspectJAdvisorFactoryTests {
73
74
75
76
77
78 protected abstract AspectJAdvisorFactory getFixture();
79
80
81 @Test
82 public void testRejectsPerCflowAspect() {
83 try {
84 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerCflowAspect(),"someBean"));
85 fail("Cannot accept cflow");
86 }
87 catch (AopConfigException ex) {
88 assertTrue(ex.getMessage().indexOf("PERCFLOW") != -1);
89 }
90 }
91
92 @Test
93 public void testRejectsPerCflowBelowAspect() {
94 try {
95 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerCflowBelowAspect(),"someBean"));
96 fail("Cannot accept cflowbelow");
97 }
98 catch (AopConfigException ex) {
99 assertTrue(ex.getMessage().indexOf("PERCFLOWBELOW") != -1);
100 }
101 }
102
103 @Test
104 public void testPerTargetAspect() throws SecurityException, NoSuchMethodException {
105 TestBean target = new TestBean();
106 int realAge = 65;
107 target.setAge(realAge);
108 TestBean itb = (TestBean) createProxy(target,
109 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(), "someBean")),
110 TestBean.class);
111 assertEquals("Around advice must NOT apply", realAge, itb.getAge());
112
113 Advised advised = (Advised) itb;
114 SyntheticInstantiationAdvisor sia = (SyntheticInstantiationAdvisor) advised.getAdvisors()[1];
115 assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
116 InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[3];
117 LazySingletonAspectInstanceFactoryDecorator maaif =
118 (LazySingletonAspectInstanceFactoryDecorator) imapa.getAspectInstanceFactory();
119 assertFalse(maaif.isMaterialized());
120
121
122 assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
123 assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut());
124
125
126 itb.getSpouse();
127
128 assertTrue(maaif.isMaterialized());
129
130 assertEquals("Around advice must apply", 0, itb.getAge());
131 assertEquals("Around advice must apply", 1, itb.getAge());
132 }
133
134 @Test
135 public void testMultiplePerTargetAspects() throws SecurityException, NoSuchMethodException {
136 TestBean target = new TestBean();
137 int realAge = 65;
138 target.setAge(realAge);
139
140 List<Advisor> advisors = new LinkedList<Advisor>();
141 PerTargetAspect aspect1 = new PerTargetAspect();
142 aspect1.count = 100;
143 aspect1.setOrder(10);
144 advisors.addAll(
145 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspect1, "someBean1")));
146 PerTargetAspect aspect2 = new PerTargetAspect();
147 aspect2.setOrder(5);
148 advisors.addAll(
149 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspect2, "someBean2")));
150 Collections.sort(advisors, new OrderComparator());
151
152 TestBean itb = (TestBean) createProxy(target, advisors, TestBean.class);
153 assertEquals("Around advice must NOT apply", realAge, itb.getAge());
154
155
156 itb.getSpouse();
157
158 assertEquals("Around advice must apply", 0, itb.getAge());
159 assertEquals("Around advice must apply", 1, itb.getAge());
160 }
161
162 @Test
163 public void testMultiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoSuchMethodException {
164 TestBean target = new TestBean();
165 int realAge = 65;
166 target.setAge(realAge);
167
168 List<Advisor> advisors = new LinkedList<Advisor>();
169 PerTargetAspectWithOrderAnnotation10 aspect1 = new PerTargetAspectWithOrderAnnotation10();
170 aspect1.count = 100;
171 advisors.addAll(
172 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspect1, "someBean1")));
173 PerTargetAspectWithOrderAnnotation5 aspect2 = new PerTargetAspectWithOrderAnnotation5();
174 advisors.addAll(
175 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspect2, "someBean2")));
176 Collections.sort(advisors, new OrderComparator());
177
178 TestBean itb = (TestBean) createProxy(target, advisors, TestBean.class);
179 assertEquals("Around advice must NOT apply", realAge, itb.getAge());
180
181
182 itb.getSpouse();
183
184 assertEquals("Around advice must apply", 0, itb.getAge());
185 assertEquals("Around advice must apply", 1, itb.getAge());
186 }
187
188 @Test
189 public void testPerThisAspect() throws SecurityException, NoSuchMethodException {
190 TestBean target = new TestBean();
191 int realAge = 65;
192 target.setAge(realAge);
193 TestBean itb = (TestBean) createProxy(target,
194 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerThisAspect(), "someBean")),
195 TestBean.class);
196 assertEquals("Around advice must NOT apply", realAge, itb.getAge());
197
198 Advised advised = (Advised) itb;
199
200 assertEquals(4, advised.getAdvisors().length);
201 SyntheticInstantiationAdvisor sia = (SyntheticInstantiationAdvisor) advised.getAdvisors()[1];
202 assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
203 InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[2];
204 LazySingletonAspectInstanceFactoryDecorator maaif =
205 (LazySingletonAspectInstanceFactoryDecorator) imapa.getAspectInstanceFactory();
206 assertFalse(maaif.isMaterialized());
207
208
209 assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
210 assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut());
211
212
213 itb.getSpouse();
214
215 assertTrue(maaif.isMaterialized());
216
217 assertTrue(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null));
218
219 assertEquals("Around advice must apply", 0, itb.getAge());
220 assertEquals("Around advice must apply", 1, itb.getAge());
221 }
222
223 @Test
224 public void testPerTypeWithinAspect() throws SecurityException, NoSuchMethodException {
225 TestBean target = new TestBean();
226 int realAge = 65;
227 target.setAge(realAge);
228 PerTypeWithinAspectInstanceFactory aif = new PerTypeWithinAspectInstanceFactory();
229 TestBean itb = (TestBean) createProxy(target,
230 getFixture().getAdvisors(aif),
231 TestBean.class);
232 assertEquals("No method calls", 0, aif.getInstantiationCount());
233 assertEquals("Around advice must now apply", 0, itb.getAge());
234
235 Advised advised = (Advised) itb;
236
237 assertEquals(4, advised.getAdvisors().length);
238 SyntheticInstantiationAdvisor sia = (SyntheticInstantiationAdvisor) advised.getAdvisors()[1];
239 assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
240 InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[2];
241 LazySingletonAspectInstanceFactoryDecorator maaif =
242 (LazySingletonAspectInstanceFactoryDecorator) imapa.getAspectInstanceFactory();
243 assertTrue(maaif.isMaterialized());
244
245
246 assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
247 assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut());
248
249
250 itb.getSpouse();
251
252 assertTrue(maaif.isMaterialized());
253
254 assertTrue(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null));
255
256 assertEquals("Around advice must still apply", 1, itb.getAge());
257 assertEquals("Around advice must still apply", 2, itb.getAge());
258
259 TestBean itb2 = (TestBean) createProxy(target,
260 getFixture().getAdvisors(aif),
261 TestBean.class);
262 assertEquals(1, aif.getInstantiationCount());
263 assertEquals("Around advice be independent for second instance", 0, itb2.getAge());
264 assertEquals(2, aif.getInstantiationCount());
265 }
266
267 @Test
268 public void testNamedPointcutAspectWithFQN() {
269 testNamedPointcuts(new NamedPointcutAspectWithFQN());
270 }
271
272 @Test
273 public void testNamedPointcutAspectWithoutFQN() {
274 testNamedPointcuts(new NamedPointcutAspectWithoutFQN());
275 }
276
277 @Test
278 public void testNamedPointcutFromAspectLibrary() {
279 testNamedPointcuts(new NamedPointcutAspectFromLibrary());
280 }
281
282 @Test
283 public void testNamedPointcutFromAspectLibraryWithBinding() {
284 TestBean target = new TestBean();
285 ITestBean itb = (ITestBean) createProxy(target,
286 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new NamedPointcutAspectFromLibraryWithBinding(),"someBean")),
287 ITestBean.class);
288 itb.setAge(10);
289 assertEquals("Around advice must apply", 20, itb.getAge());
290 assertEquals(20,target.getAge());
291 }
292
293 private void testNamedPointcuts(Object aspectInstance) {
294 TestBean target = new TestBean();
295 int realAge = 65;
296 target.setAge(realAge);
297 ITestBean itb = (ITestBean) createProxy(target,
298 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(aspectInstance,"someBean")),
299 ITestBean.class);
300 assertEquals("Around advice must apply", -1, itb.getAge());
301 assertEquals(realAge, target.getAge());
302 }
303
304 @Test
305 public void testBindingWithSingleArg() {
306 TestBean target = new TestBean();
307 ITestBean itb = (ITestBean) createProxy(target,
308 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new BindingAspectWithSingleArg(),"someBean")),
309 ITestBean.class);
310 itb.setAge(10);
311 assertEquals("Around advice must apply", 20, itb.getAge());
312 assertEquals(20,target.getAge());
313 }
314
315 @Test
316 public void testBindingWithMultipleArgsDifferentlyOrdered() {
317 ManyValuedArgs target = new ManyValuedArgs();
318 ManyValuedArgs mva = (ManyValuedArgs) createProxy(target,
319 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ManyValuedArgs(),"someBean")),
320 ManyValuedArgs.class);
321
322 String a = "a";
323 int b = 12;
324 int c = 25;
325 String d = "d";
326 StringBuffer e = new StringBuffer("stringbuf");
327 String expectedResult = a + b+ c + d + e;
328 assertEquals(expectedResult, mva.mungeArgs(a, b, c, d, e));
329 }
330
331
332
333
334 @Test
335 public void testIntroductionOnTargetNotImplementingInterface() {
336 NotLockable notLockableTarget = new NotLockable();
337 assertFalse(notLockableTarget instanceof Lockable);
338 NotLockable notLockable1 = (NotLockable) createProxy(notLockableTarget,
339 getFixture().getAdvisors(
340 new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")),
341 NotLockable.class);
342 assertTrue(notLockable1 instanceof Lockable);
343 Lockable lockable = (Lockable) notLockable1;
344 assertFalse(lockable.locked());
345 lockable.lock();
346 assertTrue(lockable.locked());
347
348 NotLockable notLockable2Target = new NotLockable();
349 NotLockable notLockable2 = (NotLockable) createProxy(notLockable2Target,
350 getFixture().getAdvisors(
351 new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")),
352 NotLockable.class);
353 assertTrue(notLockable2 instanceof Lockable);
354 Lockable lockable2 = (Lockable) notLockable2;
355 assertFalse(lockable2.locked());
356 notLockable2.setIntValue(1);
357 lockable2.lock();
358 try {
359 notLockable2.setIntValue(32);
360 fail();
361 }
362 catch (IllegalStateException ex) {
363 }
364 assertTrue(lockable2.locked());
365 }
366
367 @Test
368 public void testIntroductionAdvisorExcludedFromTargetImplementingInterface() {
369 assertTrue(AopUtils.findAdvisorsThatCanApply(
370 getFixture().getAdvisors(
371 new SingletonMetadataAwareAspectInstanceFactory(
372 new MakeLockable(),"someBean")),
373 CannotBeUnlocked.class).isEmpty());
374 assertEquals(2, AopUtils.findAdvisorsThatCanApply(getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class).size());
375 }
376
377 @Test
378 public void testIntroductionOnTargetImplementingInterface() {
379 CannotBeUnlocked target = new CannotBeUnlocked();
380 Lockable proxy = (Lockable) createProxy(target,
381
382 AopUtils.findAdvisorsThatCanApply(
383 getFixture().getAdvisors(
384 new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
385 CannotBeUnlocked.class
386 ),
387 CannotBeUnlocked.class);
388 assertThat(proxy, instanceOf(Lockable.class));
389 Lockable lockable = proxy;
390 assertTrue("Already locked", lockable.locked());
391 lockable.lock();
392 assertTrue("Real target ignores locking", lockable.locked());
393 try {
394 lockable.unlock();
395 fail();
396 }
397 catch (UnsupportedOperationException ex) {
398
399 }
400 }
401
402 @Test
403 public void testIntroductionOnTargetExcludedByTypePattern() {
404 LinkedList<Object> target = new LinkedList<Object>();
405 List<?> proxy = (List<?>) createProxy(target,
406 AopUtils.findAdvisorsThatCanApply(
407 getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
408 List.class
409 ),
410 CannotBeUnlocked.class);
411 assertFalse("Type pattern must have excluded mixin", proxy instanceof Lockable);
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433 @Test
434 @Ignore
435 public void testIntroductionWithArgumentBinding() {
436 TestBean target = new TestBean();
437
438 List<Advisor> advisors = getFixture().getAdvisors(
439 new SingletonMetadataAwareAspectInstanceFactory(new MakeITestBeanModifiable(),"someBean"));
440 advisors.addAll(getFixture().getAdvisors(
441 new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")));
442
443 Modifiable modifiable = (Modifiable) createProxy(target,
444 advisors,
445 ITestBean.class);
446 assertThat(modifiable, instanceOf(Modifiable.class));
447 Lockable lockable = (Lockable) modifiable;
448 assertFalse(lockable.locked());
449
450 ITestBean itb = (ITestBean) modifiable;
451 assertFalse(modifiable.isModified());
452 int oldAge = itb.getAge();
453 itb.setAge(oldAge + 1);
454 assertTrue(modifiable.isModified());
455 modifiable.acceptChanges();
456 assertFalse(modifiable.isModified());
457 itb.setAge(itb.getAge());
458 assertFalse("Setting same value does not modify", modifiable.isModified());
459 itb.setName("And now for something completely different");
460 assertTrue(modifiable.isModified());
461
462 lockable.lock();
463 assertTrue(lockable.locked());
464 try {
465 itb.setName("Else");
466 fail("Should be locked");
467 }
468 catch (IllegalStateException ex) {
469
470 }
471 lockable.unlock();
472 itb.setName("Tony");
473 }
474
475 @Test
476 public void testAspectMethodThrowsExceptionLegalOnSignature() {
477 TestBean target = new TestBean();
478 UnsupportedOperationException expectedException = new UnsupportedOperationException();
479 List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException),"someBean"));
480 assertEquals("One advice method was found", 1, advisors.size());
481 ITestBean itb = (ITestBean) createProxy(target,
482 advisors,
483 ITestBean.class);
484 try {
485 itb.getAge();
486 fail();
487 }
488 catch (UnsupportedOperationException ex) {
489 assertSame(expectedException, ex);
490 }
491 }
492
493
494
495 @Test
496 public void testAspectMethodThrowsExceptionIllegalOnSignature() {
497 TestBean target = new TestBean();
498 RemoteException expectedException = new RemoteException();
499 List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new ExceptionAspect(expectedException),"someBean"));
500 assertEquals("One advice method was found", 1, advisors.size());
501 ITestBean itb = (ITestBean) createProxy(target,
502 advisors,
503 ITestBean.class);
504 try {
505 itb.getAge();
506 fail();
507 }
508 catch (UndeclaredThrowableException ex) {
509 assertSame(expectedException, ex.getCause());
510 }
511 }
512
513 protected Object createProxy(Object target, List<Advisor> advisors, Class<?>... interfaces) {
514 ProxyFactory pf = new ProxyFactory(target);
515 if (interfaces.length > 1 || interfaces[0].isInterface()) {
516 pf.setInterfaces(interfaces);
517 }
518 else {
519 pf.setProxyTargetClass(true);
520 }
521
522
523 pf.addAdvice(ExposeInvocationInterceptor.INSTANCE);
524
525 for (Object a : advisors) {
526 pf.addAdvisor((Advisor) a);
527 }
528
529 pf.setExposeProxy(true);
530 return pf.getProxy();
531 }
532
533 @Test
534 public void testTwoAdvicesOnOneAspect() {
535 TestBean target = new TestBean();
536
537 TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect();
538 List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(twoAdviceAspect,"someBean"));
539 assertEquals("Two advice methods found", 2, advisors.size());
540 ITestBean itb = (ITestBean) createProxy(target,
541 advisors,
542 ITestBean.class);
543 itb.setName("");
544 assertEquals(0, itb.getAge());
545 int newAge = 32;
546 itb.setAge(newAge);
547 assertEquals(1, itb.getAge());
548 }
549
550 @Test
551 public void testAfterAdviceTypes() throws Exception {
552 Echo target = new Echo();
553
554 ExceptionHandling afterReturningAspect = new ExceptionHandling();
555 List<Advisor> advisors = getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(afterReturningAspect,"someBean"));
556 Echo echo = (Echo) createProxy(target,
557 advisors,
558 Echo.class);
559 assertEquals(0, afterReturningAspect.successCount);
560 assertEquals("", echo.echo(""));
561 assertEquals(1, afterReturningAspect.successCount);
562 assertEquals(0, afterReturningAspect.failureCount);
563 try {
564 echo.echo(new FileNotFoundException());
565 fail();
566 }
567 catch (FileNotFoundException ex) {
568
569 }
570 catch (Exception ex) {
571 fail();
572 }
573 assertEquals(1, afterReturningAspect.successCount);
574 assertEquals(1, afterReturningAspect.failureCount);
575 assertEquals(afterReturningAspect.failureCount + afterReturningAspect.successCount, afterReturningAspect.afterCount);
576 }
577
578 @Test
579 public void testFailureWithoutExplicitDeclarePrecedence() {
580 TestBean target = new TestBean();
581 MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
582 new NoDeclarePrecedenceShouldFail(), "someBean");
583 ITestBean itb = (ITestBean) createProxy(target,
584 getFixture().getAdvisors(aspectInstanceFactory), ITestBean.class);
585 itb.getAge();
586 }
587
588 @Test(expected=IllegalArgumentException.class)
589 public void testDeclarePrecedenceNotSupported() {
590 TestBean target = new TestBean();
591 MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
592 new DeclarePrecedenceShouldSucceed(), "someBean");
593 createProxy(target, getFixture().getAdvisors(aspectInstanceFactory),
594 ITestBean.class);
595 }
596
597
598
599
600
601
602
603
604
605
606
607
608 @Aspect("percflow(execution(* *(..)))")
609 public static class PerCflowAspect {
610 }
611
612
613 @Aspect("percflowbelow(execution(* *(..)))")
614 public static class PerCflowBelowAspect {
615 }
616
617
618 @Aspect("pertarget(execution(* *.getSpouse()))")
619 @Order(10)
620 public static class PerTargetAspectWithOrderAnnotation10 {
621
622 public int count;
623
624 @Around("execution(int *.getAge())")
625 public int returnCountAsAge() {
626 return count++;
627 }
628
629 @Before("execution(void *.set*(int))")
630 public void countSetter() {
631 ++count;
632 }
633 }
634
635
636 @Aspect("pertarget(execution(* *.getSpouse()))")
637 @Order(5)
638 public static class PerTargetAspectWithOrderAnnotation5 {
639
640 public int count;
641
642 @Around("execution(int *.getAge())")
643 public int returnCountAsAge() {
644 return count++;
645 }
646
647 @Before("execution(void *.set*(int))")
648 public void countSetter() {
649 ++count;
650 }
651 }
652
653
654 @Aspect("pertypewithin(org.springframework.tests.sample.beans.IOther+)")
655 public static class PerTypeWithinAspect {
656
657 public int count;
658
659 @Around("execution(int *.getAge())")
660 public int returnCountAsAge() {
661 return count++;
662 }
663
664 @Before("execution(void *.*(..))")
665 public void countAnythingVoid() {
666 ++count;
667 }
668 }
669
670
671 private class PerTypeWithinAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
672
673 private int count;
674
675 public int getInstantiationCount() {
676 return this.count;
677 }
678
679 @Override
680 public Object getAspectInstance() {
681 ++this.count;
682 return new PerTypeWithinAspect();
683 }
684
685 @Override
686 public ClassLoader getAspectClassLoader() {
687 return PerTypeWithinAspect.class.getClassLoader();
688 }
689
690 @Override
691 public AspectMetadata getAspectMetadata() {
692 return new AspectMetadata(PerTypeWithinAspect.class, "perTypeWithin");
693 }
694
695 @Override
696 public int getOrder() {
697 return Ordered.LOWEST_PRECEDENCE;
698 }
699 }
700
701
702 @Aspect
703 public static class NamedPointcutAspectWithFQN {
704
705 private ITestBean fieldThatShouldBeIgnoredBySpringAtAspectJProcessing = new TestBean();
706
707 @Pointcut("execution(* getAge())")
708 public void getAge() {
709 }
710
711 @Around("org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactoryTests.NamedPointcutAspectWithFQN.getAge()")
712 public int changeReturnValue(ProceedingJoinPoint pjp) {
713 return -1;
714 }
715 }
716
717
718 @Aspect
719 public static class NamedPointcutAspectWithoutFQN {
720 @Pointcut("execution(* getAge())")
721 public void getAge() {
722 }
723
724 @Around("getAge()")
725 public int changeReturnValue(ProceedingJoinPoint pjp) {
726 return -1;
727 }
728 }
729
730
731 @Aspect
732 public static class NamedPointcutAspectFromLibrary {
733
734 @Around("org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactoryTests.Library.propertyAccess()")
735 public int changeReturnType(ProceedingJoinPoint pjp) {
736 return -1;
737 }
738
739 @Around(value="org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactoryTests.Library.integerArgOperation(x)", argNames="x")
740 public void doubleArg(ProceedingJoinPoint pjp, int x) throws Throwable {
741 pjp.proceed(new Object[] {x*2});
742 }
743 }
744
745
746 @Aspect
747 public static class Library {
748
749 @Pointcut("execution(!void get*())")
750 public void propertyAccess() {}
751
752 @Pointcut("execution(* *(..)) && args(i)")
753 public void integerArgOperation(int i) {}
754
755 }
756
757
758 @Aspect
759 public static class NamedPointcutAspectFromLibraryWithBinding {
760
761 @Around(value="org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactoryTests.Library.integerArgOperation(x)", argNames="x")
762 public void doubleArg(ProceedingJoinPoint pjp, int x) throws Throwable {
763 pjp.proceed(new Object[] {x*2});
764 }
765 }
766
767
768 @Aspect
769 public static class BindingAspectWithSingleArg {
770
771 @Pointcut(value="args(a)", argNames="a")
772 public void setAge(int a) {}
773
774 @Around(value="setAge(age)",argNames="age")
775
776
777 public void changeReturnType(ProceedingJoinPoint pjp, int age) throws Throwable {
778 pjp.proceed(new Object[] {age*2});
779 }
780 }
781
782
783 @Aspect
784 public static class ManyValuedArgs {
785 public String mungeArgs(String a, int b, int c, String d, StringBuffer e) {
786 return a + b + c + d + e;
787 }
788
789 @Around(value="execution(String mungeArgs(..)) && args(a, b, c, d, e)",
790 argNames="b,c,d,e,a")
791 public String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuffer e, String a) throws Throwable {
792 assertEquals(a + b+ c+ d+ e, pjp.proceed());
793 return a + b + c + d + e;
794 }
795 }
796
797
798 @Aspect
799 public static class ExceptionAspect {
800 private final Exception ex;
801
802 public ExceptionAspect(Exception ex) {
803 this.ex = ex;
804 }
805
806 @Before("execution(* getAge())")
807 public void throwException() throws Exception {
808 throw ex;
809 }
810 }
811
812
813 public static class Echo {
814
815 public Object echo(Object o) throws Exception {
816 if (o instanceof Exception) {
817 throw (Exception) o;
818 }
819 return o;
820 }
821 }
822
823
824 @Aspect
825 public static class ExceptionHandling {
826 public int successCount;
827 public int failureCount;
828 public int afterCount;
829
830 @AfterReturning("execution(* echo(*))")
831 public void succeeded() {
832 ++successCount;
833 }
834
835 @AfterThrowing("execution(* echo(*))")
836 public void failed() {
837 ++failureCount;
838 }
839
840 @After("execution(* echo(*))")
841 public void invoked() {
842 ++afterCount;
843 }
844 }
845
846
847 @Aspect
848 public static class NoDeclarePrecedenceShouldFail {
849
850 @Pointcut("execution(int *.getAge())")
851 public void getAge() {
852 }
853
854 @Before("getAge()")
855 public void blowUpButDoesntMatterBecauseAroundAdviceWontLetThisBeInvoked() {
856 throw new IllegalStateException();
857 }
858
859 @Around("getAge()")
860 public int preventExecution(ProceedingJoinPoint pjp) {
861 return 666;
862 }
863 }
864
865
866 @Aspect
867 @DeclarePrecedence("test..*")
868 public static class DeclarePrecedenceShouldSucceed {
869
870 @Pointcut("execution(int *.getAge())")
871 public void getAge() {
872 }
873
874 @Before("getAge()")
875 public void blowUpButDoesntMatterBecauseAroundAdviceWontLetThisBeInvoked() {
876 throw new IllegalStateException();
877 }
878
879 @Around("getAge()")
880 public int preventExecution(ProceedingJoinPoint pjp) {
881 return 666;
882 }
883 }
884
885 }
886
887
888
889
890
891
892
893
894
895 @Aspect
896 abstract class AbstractMakeModifiable {
897
898 public interface MutableModifable extends Modifiable {
899 void markDirty();
900 }
901
902 public static class ModifiableImpl implements MutableModifable {
903 private boolean modified;
904
905 @Override
906 public void acceptChanges() {
907 modified = false;
908 }
909
910 @Override
911 public boolean isModified() {
912 return modified;
913 }
914
915 @Override
916 public void markDirty() {
917 this.modified = true;
918 }
919 }
920
921 @Before(value="execution(void set*(*)) && this(modifiable) && args(newValue)",
922 argNames="modifiable,newValue")
923 public void recordModificationIfSetterArgumentDiffersFromOldValue(JoinPoint jp,
924 MutableModifable mixin, Object newValue) {
925
926
927
928
929
930
931
932
933 if (mixin.isModified()) {
934
935
936 return;
937 }
938
939
940 Method correspondingGetter = getGetterFromSetter(((MethodSignature) jp.getSignature()).getMethod());
941 boolean modified = true;
942 if (correspondingGetter != null) {
943 try {
944 Object oldValue = correspondingGetter.invoke(jp.getTarget());
945
946 modified = !ObjectUtils.nullSafeEquals(oldValue, newValue);
947 }
948 catch (Exception ex) {
949 ex.printStackTrace();
950
951 }
952 }
953 else {
954
955 }
956 if (modified) {
957 mixin.markDirty();
958 }
959 }
960
961 private Method getGetterFromSetter(Method setter) {
962 String getterName = setter.getName().replaceFirst("set", "get");
963 try {
964 return setter.getDeclaringClass().getMethod(getterName, (Class[]) null);
965 }
966 catch (NoSuchMethodException ex) {
967
968 return null;
969 }
970 }
971
972 }
973
974
975
976
977
978
979
980 @Aspect
981 class MakeITestBeanModifiable extends AbstractMakeModifiable {
982
983 @DeclareParents(value = "org.springframework.tests.sample.beans.ITestBean+",
984 defaultImpl=ModifiableImpl.class)
985 public static MutableModifable mixin;
986
987 }
988
989
990
991
992
993
994 @Aspect
995 class MakeAnnotatedTypeModifiable extends AbstractMakeModifiable {
996
997 @DeclareParents(value = "(@org.springframework.aop.aspectj.annotation.Measured *)",
998
999 defaultImpl=DefaultLockable.class)
1000 public static Lockable mixin;
1001
1002 }
1003
1004
1005
1006
1007
1008 @Aspect
1009 class MakeLockable {
1010
1011 @DeclareParents(value = "org.springframework..*",
1012 defaultImpl=DefaultLockable.class)
1013 public static Lockable mixin;
1014
1015 @Before(value="execution(void set*(*)) && this(mixin)", argNames="mixin")
1016 public void checkNotLocked(
1017 Lockable mixin)
1018 {
1019
1020
1021 if (mixin.locked()) {
1022 throw new IllegalStateException();
1023 }
1024 }
1025
1026 }
1027
1028
1029 class CannotBeUnlocked implements Lockable, Comparable<Object> {
1030
1031 @Override
1032 public void lock() {
1033 }
1034
1035 @Override
1036 public void unlock() {
1037 throw new UnsupportedOperationException();
1038 }
1039
1040 @Override
1041 public boolean locked() {
1042 return true;
1043 }
1044
1045 @Override
1046 public int compareTo(Object arg0) {
1047 throw new UnsupportedOperationException();
1048 }
1049
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 interface Modifiable {
1059
1060 boolean isModified();
1061
1062 void acceptChanges();
1063
1064 }
1065
1066
1067
1068
1069
1070 interface AnnotatedTarget {
1071 }
1072
1073 @Measured
1074 class AnnotatedTargetImpl implements AnnotatedTarget {
1075
1076 }
1077
1078 @Retention(RetentionPolicy.RUNTIME)
1079 @interface Measured {}
1080
1081 class NotLockable {
1082
1083 private int intValue;
1084
1085 public int getIntValue() {
1086 return intValue;
1087 }
1088
1089 public void setIntValue(int intValue) {
1090 this.intValue = intValue;
1091 }
1092
1093 }
1094
1095
1096 @Aspect("perthis(execution(* *.getSpouse()))")
1097 class PerThisAspect {
1098
1099 public int count;
1100
1101
1102
1103
1104 private ITestBean fieldThatShouldBeIgnoredBySpringAtAspectJProcessing = new TestBean();
1105
1106 @Around("execution(int *.getAge())")
1107 public int returnCountAsAge() {
1108 return count++;
1109 }
1110
1111 @Before("execution(void *.set*(int))")
1112 public void countSetter() {
1113 ++count;
1114 }
1115
1116 }