1 16 17 package org.springframework.aop.framework; 18 19 import java.lang.reflect.Method ; 20 import java.lang.reflect.UndeclaredThrowableException ; 21 import java.util.HashMap ; 22 import java.util.LinkedList ; 23 import java.util.List ; 24 25 import javax.servlet.ServletException ; 26 import javax.transaction.TransactionRequiredException ; 27 28 import junit.framework.TestCase; 29 import org.aopalliance.aop.Advice; 30 import org.aopalliance.aop.AspectException; 31 import org.aopalliance.intercept.MethodInterceptor; 32 import org.aopalliance.intercept.MethodInvocation; 33 34 import org.springframework.aop.Advisor; 35 import org.springframework.aop.AfterReturningAdvice; 36 import org.springframework.aop.DynamicIntroductionAdvice; 37 import org.springframework.aop.MethodBeforeAdvice; 38 import org.springframework.aop.framework.adapter.ThrowsAdviceInterceptorTests; 39 import org.springframework.aop.interceptor.ExposeInvocationInterceptor; 40 import org.springframework.aop.interceptor.NopInterceptor; 41 import org.springframework.aop.interceptor.SerializableNopInterceptor; 42 import org.springframework.aop.support.AopUtils; 43 import org.springframework.aop.support.DefaultIntroductionAdvisor; 44 import org.springframework.aop.support.DefaultPointcutAdvisor; 45 import org.springframework.aop.support.DelegatingIntroductionInterceptor; 46 import org.springframework.aop.support.DynamicMethodMatcherPointcutAdvisor; 47 import org.springframework.aop.support.NameMatchMethodPointcut; 48 import org.springframework.aop.support.Pointcuts; 49 import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; 50 import org.springframework.aop.target.HotSwappableTargetSource; 51 import org.springframework.aop.target.SingletonTargetSource; 52 import org.springframework.beans.IOther; 53 import org.springframework.beans.ITestBean; 54 import org.springframework.beans.Person; 55 import org.springframework.beans.SerializablePerson; 56 import org.springframework.beans.TestBean; 57 import org.springframework.util.SerializationTestUtils; 58 import org.springframework.util.StopWatch; 59 60 65 public abstract class AbstractAopProxyTests extends TestCase { 66 67 protected MockTargetSource mockTargetSource = new MockTargetSource(); 68 69 75 protected void setUp() { 76 mockTargetSource.reset(); 77 } 78 79 protected void tearDown() { 80 mockTargetSource.verify(); 81 } 82 83 86 protected abstract Object createProxy(AdvisedSupport as); 87 88 protected abstract AopProxy createAopProxy(AdvisedSupport as); 89 90 93 protected boolean requiresTarget() { 94 return false; 95 } 96 97 public void testNoInterceptorsAndNoTarget() { 98 AdvisedSupport pc = 99 new AdvisedSupport(new Class [] { ITestBean.class }); 100 try { 102 AopProxy aop = createAopProxy(pc); 103 aop.getProxy(); 104 fail("Shouldn't allow no interceptors"); 105 } catch (AopConfigException ex) { 106 } 108 } 109 110 113 public void testValuesStick() { 114 int age1 = 33; 115 int age2 = 37; 116 String name = "tony"; 117 118 TestBean target1 = new TestBean(); 119 target1.setAge(age1); 120 ProxyFactory pf1 = new ProxyFactory(target1); 121 pf1.addAdvisor(new DefaultPointcutAdvisor(new NopInterceptor())); 122 pf1.addAdvisor(new DefaultPointcutAdvisor(new TimestampIntroductionInterceptor())); 123 ITestBean tb = target1; 124 125 assertEquals(age1, tb.getAge()); 126 tb.setAge(age2); 127 assertEquals(age2, tb.getAge()); 128 assertNull(tb.getName()); 129 tb.setName(name); 130 assertEquals(name, tb.getName()); 131 } 132 133 138 public void testManyProxies() { 139 int howMany = 10000; 140 StopWatch sw = new StopWatch(); 141 sw.start(getClass() + "." + getName() + ": create " + howMany + " proxies"); 142 testManyProxies(howMany); 143 sw.stop(); 144 System.out.println(sw); 145 assertTrue("Proxy creation was too slow", sw.getTotalTimeSeconds() < 25); 148 } 149 150 private void testManyProxies(int howMany) { 151 int age1 = 33; 152 TestBean target1 = new TestBean(); 153 target1.setAge(age1); 154 ProxyFactory pf1 = new ProxyFactory(target1); 155 pf1.addAdvice(new NopInterceptor()); 156 pf1.addAdvice(new NopInterceptor()); 157 ITestBean proxies[] = new ITestBean[howMany]; 158 for (int i = 0; i < howMany; i++) { 159 proxies[i] = (ITestBean) createAopProxy(pf1).getProxy(); 160 assertEquals(age1, proxies[i].getAge()); 161 } 162 } 163 164 public void testSerializationAdviceAndTargetNotSerializable() throws Exception { 165 TestBean tb = new TestBean(); 166 assertFalse(SerializationTestUtils.isSerializable(tb)); 167 168 ProxyFactory pf = new ProxyFactory(tb); 169 170 pf.addAdvice(new NopInterceptor()); 171 ITestBean proxy = (ITestBean) createAopProxy(pf).getProxy(); 172 173 assertFalse(SerializationTestUtils.isSerializable(proxy)); 174 } 175 176 public void testSerializationAdviceNotSerializable() throws Exception { 177 SerializablePerson sp = new SerializablePerson(); 178 assertTrue(SerializationTestUtils.isSerializable(sp)); 179 180 ProxyFactory pf = new ProxyFactory(sp); 181 182 Advice i = new NopInterceptor(); 184 pf.addAdvice(i); 185 assertFalse(SerializationTestUtils.isSerializable(i)); 186 Object proxy = createAopProxy(pf).getProxy(); 187 188 assertFalse(SerializationTestUtils.isSerializable(proxy)); 189 } 190 191 public void testSerializationSerializableTargetAndAdvice() throws Throwable { 192 SerializablePerson personTarget = new SerializablePerson(); 193 personTarget.setName("jim"); 194 personTarget.setAge(26); 195 196 assertTrue(SerializationTestUtils.isSerializable(personTarget)); 197 198 ProxyFactory pf = new ProxyFactory(personTarget); 199 200 CountingThrowsAdvice cta = new CountingThrowsAdvice(); 201 202 pf.addAdvice(new SerializableNopInterceptor()); 203 pf.addAdvice(new CountingBeforeAdvice()); 205 pf.addAdvice(new CountingAfterReturningAdvice()); 206 pf.addAdvice(cta); 207 Person p = (Person) createAopProxy(pf).getProxy(); 208 209 p.echo(null); 210 assertEquals(0, cta.getCalls()); 211 try { 212 p.echo(new ServletException ()); 213 } 214 catch (ServletException ex) { 215 216 } 217 assertEquals(1, cta.getCalls()); 218 219 Person p2 = (Person) SerializationTestUtils.serializeAndDeserialize(p); 221 assertNotSame(p, p2); 222 assertEquals(p.getName(), p2.getName()); 223 assertEquals(p.getAge(), p2.getAge()); 224 assertTrue("Deserialized object is an AOP proxy", AopUtils.isAopProxy(p2)); 225 226 Advised a1 = (Advised) p; 227 Advised a2 = (Advised) p2; 228 assertEquals(a1.getAdvisors().length, a2.getAdvisors().length); 230 231 assertEquals("Proxies should be equal, even after one was serialized", p, p2); 233 assertEquals("Proxies should be equal, even after one was serialized", p2, p); 234 235 NopInterceptor ni = new NopInterceptor(); 237 p2.getAge(); 238 assertEquals(0, ni.getCount()); 239 a2.addAdvice(ni); 240 p2.getAge(); 241 assertEquals(1, ni.getCount()); 242 243 cta = (CountingThrowsAdvice) a2.getAdvisors()[3].getAdvice(); 244 p2.echo(null); 245 assertEquals(1, cta.getCalls()); 246 try { 247 p2.echo(new ServletException ()); 248 } 249 catch (ServletException ex) { 250 251 } 252 assertEquals(2, cta.getCalls()); 253 254 } 255 256 261 public void testOneAdvisedObjectCallsAnother() { 262 int age1 = 33; 263 int age2 = 37; 264 265 TestBean target1 = new TestBean(); 266 ProxyFactory pf1 = new ProxyFactory(target1); 267 pf1.setExposeProxy(true); 269 NopInterceptor di1 = new NopInterceptor(); 270 pf1.addAdvice(0, di1); 271 pf1.addAdvice(1, new ProxyMatcherInterceptor()); 272 pf1.addAdvice(2, new CheckMethodInvocationIsSameInAndOutInterceptor()); 273 pf1.addAdvice(1, new CheckMethodInvocationViaThreadLocalIsSameInAndOutInterceptor()); 274 pf1.addAdvice(0, ExposeInvocationInterceptor.INSTANCE); 276 ITestBean advised1 = (ITestBean) pf1.getProxy(); 277 advised1.setAge(age1); 279 TestBean target2 = new TestBean(); 280 ProxyFactory pf2 = new ProxyFactory(target2); 281 pf2.setExposeProxy(true); 282 NopInterceptor di2 = new NopInterceptor(); 283 pf2.addAdvice(0, di2); 284 pf2.addAdvice(1, new ProxyMatcherInterceptor()); 285 pf2.addAdvice(2, new CheckMethodInvocationIsSameInAndOutInterceptor()); 286 pf2.addAdvice(1, new CheckMethodInvocationViaThreadLocalIsSameInAndOutInterceptor()); 287 pf2.addAdvice(0, ExposeInvocationInterceptor.INSTANCE); 288 ITestBean advised2 = (ITestBean) createProxy(pf2); 290 advised2.setAge(age2); 291 advised1.setSpouse(advised2); 293 assertEquals("Advised one has correct age", age1, advised1.getAge()); assertEquals("Advised two has correct age", age2, advised2.getAge()); 295 assertEquals("Advised one spouse has correct age", age2, advised1.getSpouse().getAge()); 298 assertEquals("one was invoked correct number of times", 4, di1.getCount()); 299 assertEquals("one was invoked correct number of times", 3, di2.getCount()); 301 } 302 303 304 public void testReentrance() { 305 int age1 = 33; 306 307 TestBean target1 = new TestBean(); 308 ProxyFactory pf1 = new ProxyFactory(target1); 309 NopInterceptor di1 = new NopInterceptor(); 310 pf1.addAdvice(0, di1); 311 ITestBean advised1 = (ITestBean) createProxy(pf1); 312 advised1.setAge(age1); advised1.setSpouse(advised1); 315 assertEquals("one was invoked correct number of times", 2, di1.getCount()); 316 317 assertEquals("Advised one has correct age", age1, advised1.getAge()); assertEquals("one was invoked correct number of times", 3, di1.getCount()); 319 320 assertEquals("Advised spouse has correct age", age1, advised1.getSpouse().getAge()); 322 323 assertEquals("one was invoked correct number of times", 5, di1.getCount()); 324 } 325 326 public void testTargetCanGetProxy() { 327 NopInterceptor di = new NopInterceptor(); 328 INeedsToSeeProxy target = new TargetChecker(); 329 ProxyFactory proxyFactory = new ProxyFactory(target); 330 proxyFactory.setExposeProxy(true); 331 assertTrue(proxyFactory.isExposeProxy()); 332 333 proxyFactory.addAdvice(0, di); 334 INeedsToSeeProxy proxied = (INeedsToSeeProxy) createProxy(proxyFactory); 335 assertEquals(0, di.getCount()); 336 assertEquals(0, target.getCount()); 337 proxied.incrementViaThis(); 338 assertEquals("Increment happened", 1, target.getCount()); 339 340 assertEquals("Only one invocation via AOP as use of this wasn't proxied", 1, di.getCount()); 341 assertEquals("Increment happened", 1, proxied.getCount()); 343 proxied.incrementViaProxy(); assertEquals("Increment happened", 2, target.getCount()); 345 assertEquals("3 more invocations via AOP as the first call was reentrant through the proxy", 4, di.getCount()); 346 } 347 348 349 public void testTargetCantGetProxyByDefault() { 350 NeedsToSeeProxy et = new NeedsToSeeProxy(); 351 ProxyFactory pf1 = new ProxyFactory(et); 352 assertFalse(pf1.isExposeProxy()); 353 INeedsToSeeProxy proxied = (INeedsToSeeProxy) createProxy(pf1); 354 try { 355 proxied.incrementViaProxy(); 356 fail("Should have failed to get proxy as exposeProxy wasn't set to true"); 357 } 358 catch (AspectException ex) { 359 } 361 } 362 363 public void testContext() throws Throwable { 364 testContext(true); 365 } 366 367 public void testNoContext() throws Throwable { 368 testContext(false); 369 } 370 371 374 private void testContext(final boolean context) throws Throwable { 375 final String s = "foo"; 376 MethodInterceptor mi = new MethodInterceptor() { 378 public Object invoke(MethodInvocation invocation) throws Throwable { 379 if (!context) { 380 assertNoInvocationContext(); 381 } else { 382 assertTrue("have context", ExposeInvocationInterceptor.currentInvocation() != null); 383 } 384 return s; 385 } 386 }; 387 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class }); 388 if (context) { 389 pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); 390 } 391 pc.addAdvice(mi); 392 if (requiresTarget()) { 394 pc.setTarget(new TestBean()); 395 } 396 AopProxy aop = createAopProxy(pc); 397 398 assertNoInvocationContext(); 399 ITestBean tb = (ITestBean) aop.getProxy(); 400 assertNoInvocationContext(); 401 assertTrue("correct return value", tb.getName() == s); 402 } 403 404 408 public void testTargetReturnsThis() throws Throwable { 409 TestBean raw = new OwnSpouse(); 411 412 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class }); 413 pc.setTarget(raw); 414 415 ITestBean tb = (ITestBean) createProxy(pc); 416 assertTrue("this return is wrapped in proxy", tb.getSpouse() == tb); 417 } 418 419 442 443 public void testDeclaredException() throws Throwable { 444 final Exception expectedException = new Exception (); 445 MethodInterceptor mi = new MethodInterceptor() { 447 public Object invoke(MethodInvocation invocation) throws Throwable { 448 throw expectedException; 449 } 450 }; 451 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class }); 452 pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); 453 pc.addAdvice(mi); 454 455 mockTargetSource.setTarget(new Object ()); 457 pc.setTargetSource(mockTargetSource); 458 AopProxy aop = createAopProxy(pc); 459 460 try { 461 ITestBean tb = (ITestBean) aop.getProxy(); 462 tb.exceptional(expectedException); 464 fail("Should have thrown exception raised by interceptor"); 465 } 466 catch (Exception thrown) { 467 assertEquals("exception matches", expectedException, thrown); 468 } 469 } 470 471 476 public void testUndeclaredCheckedException() throws Throwable { 477 final Exception unexpectedException = new Exception (); 478 MethodInterceptor mi = new MethodInterceptor() { 480 public Object invoke(MethodInvocation invocation) throws Throwable { 481 throw unexpectedException; 482 } 483 }; 484 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class }); 485 pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); 486 pc.addAdvice(mi); 487 488 pc.setTarget(new TestBean()); 490 AopProxy aop = createAopProxy(pc); 491 ITestBean tb = (ITestBean) aop.getProxy(); 492 493 try { 494 tb.getAge(); 496 fail("Should have wrapped exception raised by interceptor"); 497 } 498 catch (UndeclaredThrowableException thrown) { 499 assertEquals("exception matches", unexpectedException, thrown.getUndeclaredThrowable()); 500 } 501 catch (Exception ex) { 505 ex.printStackTrace(); 506 fail("Didn't expect exception: " + ex); 507 } 508 } 509 510 public void testUndeclaredUnheckedException() throws Throwable { 511 final RuntimeException unexpectedException = new RuntimeException (); 512 MethodInterceptor mi = new MethodInterceptor() { 514 public Object invoke(MethodInvocation invocation) throws Throwable { 515 throw unexpectedException; 516 } 517 }; 518 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class }); 519 pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); 520 pc.addAdvice(mi); 521 522 pc.setTarget(new TestBean()); 524 AopProxy aop = createAopProxy(pc); 525 ITestBean tb = (ITestBean) aop.getProxy(); 526 527 try { 528 tb.getAge(); 530 fail("Should have wrapped exception raised by interceptor"); 531 } 532 catch (RuntimeException thrown) { 533 assertEquals("exception matches", unexpectedException, thrown); 534 } 535 } 539 540 546 public void testTargetCanGetInvocationEvenIfNoAdviceChain() throws Throwable { 547 NeedsToSeeProxy target = new NeedsToSeeProxy(); 548 AdvisedSupport pc = new AdvisedSupport(new Class [] { INeedsToSeeProxy.class } ); 549 pc.setTarget(target); 550 pc.setExposeProxy(true); 551 552 AopProxy aop = createAopProxy(pc); 554 INeedsToSeeProxy proxied = (INeedsToSeeProxy) aop.getProxy(); 555 proxied.incrementViaProxy(); 557 } 558 559 public void testTargetCanGetInvocation() throws Throwable { 560 final InvocationCheckExposedInvocationTestBean expectedTarget = new InvocationCheckExposedInvocationTestBean(); 561 562 AdvisedSupport pc = new AdvisedSupport(new Class [] { ITestBean.class, IOther.class }); 563 pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); 564 TrapTargetInterceptor tii = new TrapTargetInterceptor() { 565 public Object invoke(MethodInvocation invocation) throws Throwable { 566 assertEquals("Target is correct", expectedTarget, invocation.getThis()); 568 return super.invoke(invocation); 569 } 570 }; 571 pc.addAdvice(tii); 572 pc.setTarget(expectedTarget); 573 AopProxy aop = createAopProxy(pc); 574 575 ITestBean tb = (ITestBean) aop.getProxy(); 576 tb.getName(); 577 580 582 } 587 588 591 private void assertNoInvocationContext() { 592 try { 593 ExposeInvocationInterceptor.currentInvocation(); 594 fail("Expected no invocation context"); 595 } catch (AspectException ex) { 596 } 598 } 599 600 603 public void testMixinWithIntroductionAdvisor() throws Throwable { 604 TestBean tb = new TestBean(); 605 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 606 pc.addAdvisor(new LockMixinAdvisor()); 607 pc.setTarget(tb); 608 609 testTestBeanIntroduction(pc); 610 } 611 612 public void testMixinWithIntroductionInfo() throws Throwable { 613 TestBean tb = new TestBean(); 614 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 615 pc.addAdvice(new LockMixin()); 617 pc.setTarget(tb); 618 619 testTestBeanIntroduction(pc); 620 } 621 622 private void testTestBeanIntroduction(ProxyFactory pc) { 623 int newAge = 65; 624 ITestBean itb = (ITestBean) createProxy(pc); 625 itb.setAge(newAge); 626 assertTrue(itb.getAge() == newAge); 627 628 Lockable lockable = (Lockable) itb; 629 assertFalse(lockable.locked()); 630 lockable.lock(); 631 632 assertTrue(itb.getAge() == newAge); 633 try { 634 itb.setAge(1); 635 fail("Setters should fail when locked"); 636 } 637 catch (LockedException ex) { 638 } 640 assertTrue(itb.getAge() == newAge); 641 642 assertTrue(lockable.locked()); 644 lockable.unlock(); 645 itb.setAge(1); 646 assertTrue(itb.getAge() == 1); 647 } 648 649 650 public void testReplaceArgument() throws Throwable { 651 TestBean tb = new TestBean(); 652 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 653 pc.setTarget(tb); 654 pc.addAdvisor(new StringSetterNullReplacementAdvice()); 655 656 ITestBean t = (ITestBean) pc.getProxy(); 657 int newAge = 5; 658 t.setAge(newAge); 659 assertTrue(t.getAge() == newAge); 660 String newName = "greg"; 661 t.setName(newName); 662 assertEquals(newName, t.getName()); 663 664 t.setName(null); 665 assertTrue(t.getName().equals("")); 667 } 668 669 public void testCanCastProxyToProxyConfig() throws Throwable { 670 TestBean tb = new TestBean(); 671 ProxyFactory pc = new ProxyFactory(tb); 672 NopInterceptor di = new NopInterceptor(); 673 pc.addAdvice(0, di); 674 675 ITestBean t = (ITestBean) createProxy(pc); 676 assertEquals(0, di.getCount()); 677 t.setAge(23); 678 assertEquals(23, t.getAge()); 679 assertEquals(2, di.getCount()); 680 681 Advised advised = (Advised) t; 682 assertEquals("Have 1 advisor", 1, advised.getAdvisors().length); 683 assertEquals(di, advised.getAdvisors()[0].getAdvice()); 684 NopInterceptor di2 = new NopInterceptor(); 685 advised.addAdvice(1, di2); 686 t.getName(); 687 assertEquals(3, di.getCount()); 688 assertEquals(1, di2.getCount()); 689 advised.removeAdvisor(0); 691 t.getAge(); 692 assertEquals(3, di.getCount()); 694 assertEquals(2, di2.getCount()); 695 696 CountingBeforeAdvice cba = new CountingBeforeAdvice(); 697 assertEquals(0, cba.getCalls()); 698 advised.addAdvice(cba); 699 t.setAge(16); 700 assertEquals(16, t.getAge()); 701 assertEquals(2, cba.getCalls()); 702 } 703 704 public void testAdviceImplementsIntroductionInfo() throws Throwable { 705 TestBean tb = new TestBean(); 706 String name = "tony"; 707 tb.setName(name); 708 ProxyFactory pc = new ProxyFactory(tb); 709 NopInterceptor di = new NopInterceptor(); 710 pc.addAdvice(di); 711 final long ts = 37; 712 pc.addAdvice(new DelegatingIntroductionInterceptor(new TimeStamped() { 713 public long getTimeStamp() { 714 return ts; 715 } 716 })); 717 718 ITestBean proxied = (ITestBean) createProxy(pc); 719 assertEquals(name, proxied.getName()); 720 TimeStamped intro = (TimeStamped) proxied; 721 assertEquals(ts, intro.getTimeStamp()); 722 } 723 724 public void testCannotAddDynamicIntroductionAdviceExceptInIntroductionAdvice() throws Throwable { 725 TestBean target = new TestBean(); 726 target.setAge(21); 727 ProxyFactory pc = new ProxyFactory(target); 728 try { 729 pc.addAdvice(new DummyIntroductionAdviceImpl()); 730 fail("Shouldn't be able to add introduction interceptor except via introduction advice"); 731 } 732 catch (AopConfigException ex) { 733 assertTrue(ex.getMessage().indexOf("ntroduction") > -1); 734 } 735 ITestBean proxied = (ITestBean) createProxy(pc); 737 assertEquals(target.getAge(), proxied.getAge()); 738 } 739 740 public void testRejectsBogusDynamicIntroductionAdviceWithNoAdapter() throws Throwable { 741 TestBean target = new TestBean(); 742 target.setAge(21); 743 ProxyFactory pc = new ProxyFactory(target); 744 pc.addAdvisor(new DefaultIntroductionAdvisor(new DummyIntroductionAdviceImpl(), Comparable .class)); 745 try { 746 ITestBean proxied = (ITestBean) createProxy(pc); 748 proxied.getName(); 749 fail("Bogus introduction"); 750 } 751 catch (Exception ex) { 752 } 757 } 758 759 763 public void testCannotAddIntroductionAdviceWithUnimplementedInterface() throws Throwable { 764 TestBean target = new TestBean(); 765 target.setAge(21); 766 ProxyFactory pc = new ProxyFactory(target); 767 try { 768 pc.addAdvisor(0, new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor(), ITestBean.class)); 769 fail("Shouldn't be able to add introduction advice introducing an unimplemented interface"); 770 } 771 catch (IllegalArgumentException ex) { 772 } 774 ITestBean proxied = (ITestBean) createProxy(pc); 776 assertEquals(target.getAge(), proxied.getAge()); 777 } 778 779 783 public void testIntroductionThrowsUncheckedException() throws Throwable { 784 TestBean target = new TestBean(); 785 target.setAge(21); 786 ProxyFactory pc = new ProxyFactory(target); 787 788 class MyDi extends DelegatingIntroductionInterceptor implements TimeStamped { 789 792 public long getTimeStamp() { 793 throw new UnsupportedOperationException (); 794 } 795 } 796 pc.addAdvisor(new DefaultIntroductionAdvisor(new MyDi())); 797 798 TimeStamped ts = (TimeStamped) createProxy(pc); 799 try { 800 ts.getTimeStamp(); 801 fail("Should throw UnsupportedOperationException"); 802 } 803 catch (UnsupportedOperationException ex) { 804 } 805 } 806 807 810 public void testCannotAddIntroductionAdviceToIntroduceClass() throws Throwable { 811 TestBean target = new TestBean(); 812 target.setAge(21); 813 ProxyFactory pc = new ProxyFactory(target); 814 try { 815 pc.addAdvisor(0, new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor(), TestBean.class)); 816 fail("Shouldn't be able to add introduction advice that introduces a class, rather than an interface"); 817 } 818 catch (IllegalArgumentException ex) { 819 assertTrue(ex.getMessage().indexOf("interface") > -1); 820 } 821 ITestBean proxied = (ITestBean) createProxy(pc); 823 assertEquals(target.getAge(), proxied.getAge()); 824 } 825 826 public void testCannotAddInterceptorWhenFrozen() throws Throwable { 827 TestBean target = new TestBean(); 828 target.setAge(21); 829 ProxyFactory pc = new ProxyFactory(target); 830 assertFalse(pc.isFrozen()); 831 pc.addAdvice(new NopInterceptor()); 832 ITestBean proxied = (ITestBean) createProxy(pc); 833 pc.setFrozen(true); 834 try { 835 pc.addAdvice(0, new NopInterceptor()); 836 fail("Shouldn't be able to add interceptor when frozen"); 837 } 838 catch (AopConfigException ex) { 839 assertTrue(ex.getMessage().indexOf("frozen") > -1); 840 } 841 assertEquals(target.getAge(), proxied.getAge()); 843 assertEquals(1, ((Advised) proxied).getAdvisors().length); 844 } 845 846 849 public void testCannotAddAdvisorWhenFrozenUsingCast() throws Throwable { 850 TestBean target = new TestBean(); 851 target.setAge(21); 852 ProxyFactory pc = new ProxyFactory(target); 853 assertFalse(pc.isFrozen()); 854 pc.addAdvice(new NopInterceptor()); 855 ITestBean proxied = (ITestBean) createProxy(pc); 856 pc.setFrozen(true); 857 Advised advised = (Advised) proxied; 858 859 assertTrue(pc.isFrozen()); 860 try { 861 advised.addAdvisor(new DefaultPointcutAdvisor(new NopInterceptor())); 862 fail("Shouldn't be able to add Advisor when frozen"); 863 } 864 catch (AopConfigException ex) { 865 assertTrue(ex.getMessage().indexOf("frozen") > -1); 866 } 867 assertEquals(target.getAge(), proxied.getAge()); 869 assertEquals(1, advised.getAdvisors().length); 870 } 871 872 public void testCannotRemoveAdvisorWhenFrozen() throws Throwable { 873 TestBean target = new TestBean(); 874 target.setAge(21); 875 ProxyFactory pc = new ProxyFactory(target); 876 assertFalse(pc.isFrozen()); 877 pc.addAdvice(new NopInterceptor()); 878 ITestBean proxied = (ITestBean) createProxy(pc); 879 pc.setFrozen(true); 880 Advised advised = (Advised) proxied; 881 882 assertTrue(pc.isFrozen()); 883 try { 884 advised.removeAdvisor(0); 885 fail("Shouldn't be able to remove Advisor when frozen"); 886 } 887 catch (AopConfigException ex) { 888 assertTrue(ex.getMessage().indexOf("frozen") > -1); 889 } 890 assertEquals(1, advised.getAdvisors().length); 892 pc.setFrozen(false); 893 advised.removeAdvisor(0); 895 assertEquals(target.getAge(), proxied.getAge()); 897 assertEquals(0, advised.getAdvisors().length); 898 } 899 900 public void testUseAsHashKey() { 901 TestBean target1 = new TestBean(); 902 ProxyFactory pf1 = new ProxyFactory(target1); 903 pf1.addAdvice(new NopInterceptor()); 904 ITestBean proxy1 = (ITestBean) createProxy(pf1); 905 906 TestBean target2 = new TestBean(); 907 ProxyFactory pf2 = new ProxyFactory(target2); 908 pf2.addAdvisor(new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor())); 909 ITestBean proxy2 = (ITestBean) createProxy(pf2); 910 911 HashMap h = new HashMap (); 912 Object value1 = new Object (); 913 Object value2 = new Object (); 914 assertNull(h.get(proxy1)); 915 h.put(proxy1, value1); 916 h.put(proxy2, value2); 917 assertEquals(h.get(proxy1), value1); 918 assertEquals(h.get(proxy2), value2); 919 } 920 921 924 public void testProxyConfigString() { 925 TestBean target = new TestBean(); 926 ProxyFactory pc = new ProxyFactory(target); 927 pc.setInterfaces(new Class [] { ITestBean.class } ); 928 pc.addAdvice(new NopInterceptor()); 929 MethodBeforeAdvice mba = new CountingBeforeAdvice(); 930 Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut(), mba); 931 pc.addAdvisor(advisor); 932 ITestBean proxied = (ITestBean) createProxy(pc); 933 934 String proxyConfigString = ((Advised) proxied).toProxyConfigString(); 935 assertTrue(proxyConfigString.indexOf(advisor.toString()) != -1); 936 assertTrue(proxyConfigString.indexOf("1 interface") != -1); 937 } 938 939 public void testCanPreventCastToAdvisedUsingOpaque() { 940 TestBean target = new TestBean(); 941 ProxyFactory pc = new ProxyFactory(target); 942 pc.setInterfaces(new Class [] { ITestBean.class } ); 943 pc.addAdvice(new NopInterceptor()); 944 CountingBeforeAdvice mba = new CountingBeforeAdvice(); 945 Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut().addMethodName("setAge"), mba); 946 pc.addAdvisor(advisor); 947 assertFalse("Opaque defaults to false", pc.isOpaque()); 948 pc.setOpaque(true); 949 assertTrue("Opaque now true for this config", pc.isOpaque()); 950 ITestBean proxied = (ITestBean) createProxy(pc); 951 proxied.setAge(10); 952 assertEquals(10, proxied.getAge()); 953 assertEquals(1, mba.getCalls()); 954 955 assertFalse("Cannot be cast to Advised", proxied instanceof Advised); 956 } 957 958 public void testAdviceSupportListeners() throws Throwable { 959 TestBean target = new TestBean(); 960 target.setAge(21); 961 962 ProxyFactory pc = new ProxyFactory(target); 963 CountingAdvisorListener l = new CountingAdvisorListener(pc); 964 pc.addListener(l); 965 RefreshCountingAdvisorChainFactory acf = new RefreshCountingAdvisorChainFactory(); 966 pc.setAdvisorChainFactory(acf); 968 assertFalse(pc.isActive()); 969 assertEquals(0, l.activates); 970 assertEquals(0, acf.refreshes); 971 ITestBean proxied = (ITestBean) createProxy(pc); 972 assertEquals(1, acf.refreshes); 973 assertEquals(1, l.activates); 974 assertTrue(pc.isActive()); 975 assertEquals(target.getAge(), proxied.getAge()); 976 assertEquals(0, l.adviceChanges); 977 NopInterceptor di = new NopInterceptor(); 978 pc.addAdvice(0, di); 979 assertEquals(1, l.adviceChanges); 980 assertEquals(2, acf.refreshes); 981 assertEquals(target.getAge(), proxied.getAge()); 982 pc.removeAdvice(di); 983 assertEquals(2, l.adviceChanges); 984 assertEquals(3, acf.refreshes); 985 assertEquals(target.getAge(), proxied.getAge()); 986 pc.getProxy(); 987 assertEquals(1, l.activates); 988 989 pc.removeListener(l); 990 assertEquals(2, l.adviceChanges); 991 pc.addAdvisor(new DefaultPointcutAdvisor(new NopInterceptor())); 992 assertEquals(2, l.adviceChanges); 994 } 995 996 public void testExistingProxyChangesTarget() throws Throwable { 997 TestBean tb1 = new TestBean(); 998 tb1.setAge(33); 999 1000 TestBean tb2 = new TestBean(); 1001 tb2.setAge(26); 1002 tb2.setName("Juergen"); 1003 TestBean tb3 = new TestBean(); 1004 tb3.setAge(37); 1005 ProxyFactory pc = new ProxyFactory(tb1); 1006 NopInterceptor nop = new NopInterceptor(); 1007 pc.addAdvice(nop); 1008 ITestBean proxy = (ITestBean) createProxy(pc); 1009 assertEquals(nop.getCount(), 0); 1010 assertEquals(tb1.getAge(), proxy.getAge()); 1011 assertEquals(nop.getCount(), 1); 1012 pc.setTarget(tb2); 1014 assertEquals(tb2.getAge(), proxy.getAge()); 1015 assertEquals(nop.getCount(), 2); 1016 1017 HotSwappableTargetSource hts = new HotSwappableTargetSource(tb3); 1019 pc.setTargetSource(hts); 1020 assertEquals(tb3.getAge(), proxy.getAge()); 1021 assertEquals(nop.getCount(), 3); 1022 hts.swap(tb1); 1023 assertEquals(tb1.getAge(), proxy.getAge()); 1024 tb1.setName("Colin"); 1025 assertEquals(tb1.getName(), proxy.getName()); 1026 assertEquals(nop.getCount(), 5); 1027 1028 Advised advised = (Advised) proxy; 1030 assertSame(hts, advised.getTargetSource()); 1031 SingletonTargetSource sts = new SingletonTargetSource(tb2); 1032 advised.setTargetSource(sts); 1033 assertEquals(tb2.getName(), proxy.getName()); 1034 assertSame(sts, advised.getTargetSource()); 1035 assertEquals(tb2.getAge(), proxy.getAge()); 1036 } 1037 1038 1039 public static class CountingAdvisorListener implements AdvisedSupportListener { 1040 1041 public int adviceChanges; 1042 public int activates; 1043 private AdvisedSupport expectedSource; 1044 1045 public CountingAdvisorListener(AdvisedSupport expectedSource) { 1046 this.expectedSource = expectedSource; 1047 } 1048 1049 public void adviceChanged(AdvisedSupport as) { 1050 assertEquals(expectedSource, as); 1051 ++adviceChanges; 1052 } 1053 1054 public void activated(AdvisedSupport as) { 1055 assertEquals(expectedSource, as); 1056 ++activates; 1057 } 1058 } 1059 1060 1061 public static class RefreshCountingAdvisorChainFactory implements AdvisorChainFactory { 1062 1063 public int refreshes; 1064 1065 public void adviceChanged(AdvisedSupport pc) { 1066 ++refreshes; 1067 } 1068 1069 public List getInterceptorsAndDynamicInterceptionAdvice(Advised pc, Object proxy, Method method, Class targetClass) { 1070 return AdvisorChainFactoryUtils.calculateInterceptorsAndDynamicInterceptionAdvice(pc, proxy, method, targetClass); 1071 } 1072 1073 public void activated(AdvisedSupport as) { 1074 ++refreshes; 1075 } 1076 } 1077 1078 1079 1082 public static class StringSetterNullReplacementAdvice extends DynamicMethodMatcherPointcutAdvisor { 1083 1084 private static MethodInterceptor cleaner = new MethodInterceptor() { 1085 public Object invoke(MethodInvocation mi) throws Throwable { 1086 mi.getArguments()[0] = ""; 1088 return mi.proceed(); 1089 } 1090 }; 1091 1092 public StringSetterNullReplacementAdvice() { 1093 super(cleaner); 1094 } 1095 1096 public boolean matches(Method m, Class targetClass, Object [] args){ return args[0] == null; 1098 } 1099 1100 public boolean matches(Method m, Class targetClass){ return m.getName().startsWith("set") && 1102 m.getParameterTypes().length == 1 && 1103 m.getParameterTypes()[0].equals(String .class); 1104 } 1105 } 1106 1107 1108 public void testDynamicMethodPointcutThatAlwaysAppliesStatically() throws Throwable { 1109 TestBean tb = new TestBean(); 1110 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 1111 TestDynamicPointcutAdvice dp = new TestDynamicPointcutAdvice(new NopInterceptor(), "getAge"); 1112 pc.addAdvisor(dp); 1113 pc.setTarget(tb); 1114 ITestBean it = (ITestBean) createProxy(pc); 1115 assertEquals(dp.count, 0); 1116 int age = it.getAge(); 1117 assertEquals(dp.count, 1); 1118 it.setAge(11); 1119 assertEquals(it.getAge(), 11); 1120 assertEquals(dp.count, 2); 1121 } 1122 1123 public void testDynamicMethodPointcutThatAppliesStaticallyOnlyToSetters() throws Throwable { 1124 TestBean tb = new TestBean(); 1125 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 1126 TestDynamicPointcutAdvice dp = new TestDynamicPointcutForSettersOnly(new NopInterceptor(), "Age"); 1128 pc.addAdvisor(dp); 1129 this.mockTargetSource.setTarget(tb); 1130 pc.setTargetSource(mockTargetSource); 1131 ITestBean it = (ITestBean) createProxy(pc); 1132 assertEquals(dp.count, 0); 1133 int age = it.getAge(); 1134 assertEquals(0, dp.count); 1136 it.setAge(11); 1137 assertEquals(it.getAge(), 11); 1138 assertEquals(dp.count, 1); 1139 it.setName("joe"); 1141 assertEquals(dp.count, 1); 1142 } 1143 1144 public void testStaticMethodPointcut() throws Throwable { 1145 TestBean tb = new TestBean(); 1146 ProxyFactory pc = new ProxyFactory(new Class [] { ITestBean.class }); 1147 NopInterceptor di = new NopInterceptor(); 1148 TestStaticPointcutAdvice sp = new TestStaticPointcutAdvice(di, "getAge"); 1149 pc.addAdvisor(sp); 1150 pc.setTarget(tb); 1151 ITestBean it = (ITestBean) createProxy(pc); 1152 assertEquals(di.getCount(), 0); 1153 int age = it.getAge(); 1154 assertEquals(di.getCount(), 1); 1155 it.setAge(11); 1156 assertEquals(it.getAge(), 11); 1157 assertEquals(di.getCount(), 2); 1158 } 1159 1160 1164 public void testCloneInvocationToProceedThreeTimes() throws Throwable { 1165 TestBean tb = new TestBean(); 1166 ProxyFactory pc = new ProxyFactory(tb); 1167 pc.addInterface(ITestBean.class); 1168 1169 MethodInterceptor twoBirthdayInterceptor = new MethodInterceptor() { 1170 public Object invoke(MethodInvocation mi) throws Throwable { 1171 MethodInvocation clone1 = ((ReflectiveMethodInvocation) mi).invocableClone(); 1174 MethodInvocation clone2 = ((ReflectiveMethodInvocation) mi).invocableClone(); 1175 clone1.proceed(); 1176 clone2.proceed(); 1177 return mi.proceed(); 1178 } 1179 }; 1180 StaticMethodMatcherPointcutAdvisor advisor = new StaticMethodMatcherPointcutAdvisor(twoBirthdayInterceptor) { 1181 public boolean matches(Method m, Class targetClass) { 1182 return "haveBirthday".equals(m.getName()); 1183 } 1184 }; 1185 pc.addAdvisor(advisor); 1186 ITestBean it = (ITestBean) createProxy(pc); 1187 1188 final int age = 20; 1189 it.setAge(age); 1190 assertEquals(age, it.getAge()); 1191 assertEquals(age + 2, it.haveBirthday()); 1193 assertEquals(age + 3, it.getAge()); 1195 } 1196 1197 1200 public void testCanChangeArgumentsIndependentlyOnClonedInvocation() throws Throwable { 1201 TestBean tb = new TestBean(); 1202 ProxyFactory pc = new ProxyFactory(tb); 1203 pc.addInterface(ITestBean.class); 1204 1205 1208 MethodInterceptor nameReverter = new MethodInterceptor() { 1209 public Object invoke(MethodInvocation mi) throws Throwable { 1210 MethodInvocation clone = ((ReflectiveMethodInvocation) mi).invocableClone(); 1211 String oldName = ((ITestBean) mi.getThis()).getName(); 1212 clone.getArguments()[0] = oldName; 1213 mi.proceed(); 1215 return clone.proceed(); 1216 } 1217 }; 1218 1219 class NameSaver implements MethodInterceptor { 1220 private List names = new LinkedList (); 1221 1222 public Object invoke(MethodInvocation mi) throws Throwable { 1223 names.add(mi.getArguments()[0]); 1224 return mi.proceed(); 1225 } 1226 } 1227 1228 NameSaver saver = new NameSaver(); 1229 1230 pc.addAdvisor(new DefaultPointcutAdvisor(Pointcuts.SETTERS, nameReverter)); 1231 pc.addAdvisor(new DefaultPointcutAdvisor(Pointcuts.SETTERS, saver)); 1232 ITestBean it = (ITestBean) createProxy(pc); 1233 1234 String name1 = "tony"; 1235 String name2 = "gordon"; 1236 1237 tb.setName(name1); 1238 assertEquals(name1, tb.getName()); 1239 1240 it.setName(name2); 1241 assertEquals(name1, it.getName()); 1243 assertEquals(2, saver.names.size()); 1244 assertEquals(name2, saver.names.get(0)); 1245 assertEquals(name1, saver.names.get(1)); 1246 } 1247 1248 public static interface IOverloads { 1249 void overload(); 1250 int overload(int i); 1251 String overload(String foo); 1252 void noAdvice(); 1253 } 1254 1255 public static class Overloads implements IOverloads { 1256 public void overload() { 1257 } 1258 public int overload(int i) { 1259 return i; 1260 } 1261 public String overload(String s) { 1262 return s; 1263 } 1264 public void noAdvice() { 1265 } 1266 } 1267 1268 public void testOverloadedMethodsWithDifferentAdvice() throws Throwable { 1269 Overloads target = new Overloads(); 1270 ProxyFactory pc = new ProxyFactory(target); 1271 NopInterceptor overLoadVoids = new NopInterceptor(); 1272 pc.addAdvisor(new StaticMethodMatcherPointcutAdvisor(overLoadVoids) { 1273 public boolean matches(Method m, Class targetClass) { 1274 return m.getName().equals("overload") && m.getParameterTypes().length == 0; 1275 } 1276 }); 1277 NopInterceptor overLoadInts = new NopInterceptor(); 1278 pc.addAdvisor(new StaticMethodMatcherPointcutAdvisor(overLoadInts) { 1279 public boolean matches(Method m, Class targetClass) { 1280 return m.getName().equals("overload") && m.getParameterTypes().length == 1 && 1281 m.getParameterTypes()[0].equals(int.class); 1282 } 1283 }); 1284 1285 IOverloads proxy = (IOverloads) createProxy(pc); 1286 assertEquals(0, overLoadInts.getCount()); 1287 assertEquals(0, overLoadVoids.getCount()); 1288 proxy.overload(); 1289 assertEquals(0, overLoadInts.getCount()); 1290 assertEquals(1, overLoadVoids.getCount()); 1291 assertEquals(25, proxy.overload(25)); 1292 assertEquals(1, overLoadInts.getCount()); 1293 assertEquals(1, overLoadVoids.getCount()); 1294 proxy.noAdvice(); 1295 assertEquals(1, overLoadInts.getCount()); 1296 assertEquals(1, overLoadVoids.getCount()); 1297 } 1298 1299 public void testEquals() { 1300 IOther a = new AllInstancesAreEqual(); 1301 IOther b = new AllInstancesAreEqual(); 1302 NopInterceptor i1 = new NopInterceptor(); 1303 NopInterceptor i2 = new NopInterceptor(); 1304 ProxyFactory pfa = new ProxyFactory(a); 1305 pfa.addAdvice(i1); 1306 ProxyFactory pfb = new ProxyFactory(b); 1307 pfb.addAdvice(i2); 1308 IOther proxyA = (IOther) createProxy(pfa); 1309 IOther proxyB = (IOther) createProxy(pfb); 1310 1311 assertEquals(pfa.getAdvisors().length, pfb.getAdvisors().length); 1312 1313 assertTrue(a.equals(b)); 1314 assertTrue(i1.equals(i2)); 1315 assertTrue(proxyA.equals(proxyB)); 1316 assertFalse(proxyA.equals(a)); 1318 1319 assertEquals(0, i1.getCount()); 1321 1322 proxyA.absquatulate(); 1325 assertEquals(1, i1.getCount()); 1326 assertFalse(proxyA.equals(proxyB)); 1327 } 1328 1329 public void testBeforeAdvisorIsInvoked() { 1330 CountingBeforeAdvice cba = new CountingBeforeAdvice(); 1331 Advisor matchesNoArgs = new StaticMethodMatcherPointcutAdvisor(cba) { 1332 public boolean matches(Method m, Class targetClass) { 1333 return m.getParameterTypes().length == 0; 1334 } 1335 }; 1336 TestBean target = new TestBean(); 1337 target.setAge(80); 1338 ProxyFactory pf = new ProxyFactory(target); 1339 pf.addAdvice(new NopInterceptor()); 1340 pf.addAdvisor(matchesNoArgs); 1341 assertEquals("Advisor was added", matchesNoArgs, pf.getAdvisors()[1]); 1342 ITestBean proxied = (ITestBean) createProxy(pf); 1343 assertEquals(0, cba.getCalls()); 1344 assertEquals(0, cba.getCalls("getAge")); 1345 assertEquals(target.getAge(), proxied.getAge()); 1346 assertEquals(1, cba.getCalls()); 1347 assertEquals(1, cba.getCalls("getAge")); 1348 assertEquals(0, cba.getCalls("setAge")); 1349 proxied.setAge(26); 1351 assertEquals(1, cba.getCalls()); 1352 assertEquals(26, proxied.getAge()); 1353 } 1354 1355 public void testMultiAdvice() throws Throwable { 1356 CountingMultiAdvice cca = new CountingMultiAdvice(); 1357 Advisor matchesNoArgs = new StaticMethodMatcherPointcutAdvisor(cca) { 1358 public boolean matches(Method m, Class targetClass) { 1359 return m.getParameterTypes().length == 0 || "exceptional".equals(m.getName()); 1360 } 1361 }; 1362 TestBean target = new TestBean(); 1363 target.setAge(80); 1364 ProxyFactory pf = new ProxyFactory(target); 1365 pf.addAdvice(new NopInterceptor()); 1366 pf.addAdvisor(matchesNoArgs); 1367 assertEquals("Advisor was added", matchesNoArgs, pf.getAdvisors()[1]); 1368 ITestBean proxied = (ITestBean) createProxy(pf); 1369 1370 1391 } 1392 1393 public void testBeforeAdviceThrowsException() { 1394 final RuntimeException rex = new RuntimeException (); 1395 CountingBeforeAdvice ba = new CountingBeforeAdvice() { 1396 public void before(Method m, Object [] args, Object target) throws Throwable { 1397 super.before(m, args, target); 1398 if (m.getName().startsWith("set")) 1399 throw rex; 1400 } 1401 }; 1402 1403 TestBean target = new TestBean(); 1404 target.setAge(80); 1405 NopInterceptor nop1 = new NopInterceptor(); 1406 NopInterceptor nop2 = new NopInterceptor(); 1407 ProxyFactory pf = new ProxyFactory(target); 1408 pf.addAdvice(nop1); 1409 pf.addAdvice(ba); 1410 pf.addAdvice(nop2); 1411 ITestBean proxied = (ITestBean) createProxy(pf); 1412 assertEquals(target.getAge(), proxied.getAge()); 1414 assertEquals(1, ba.getCalls()); 1415 assertEquals(1, ba.getCalls("getAge")); 1416 assertEquals(1, nop1.getCount()); 1417 assertEquals(1, nop2.getCount()); 1418 try { 1420 proxied.setAge(26); 1421 fail("before advice should have ended chain"); 1422 } 1423 catch (RuntimeException ex) { 1424 assertEquals(rex, ex); 1425 } 1426 assertEquals(2, ba.getCalls()); 1427 assertEquals(2, nop1.getCount()); 1428 assertEquals(1, nop2.getCount()); 1430 assertEquals(target.getAge(), proxied.getAge()); 1432 } 1433 1434 1435 public void testAfterReturningAdvisorIsInvoked() { 1436 class SummingAfterAdvice implements AfterReturningAdvice { 1437 public int sum; 1438 public void afterReturning(Object returnValue, Method m, Object [] args, Object target) throws Throwable { 1439 sum += ((Integer ) returnValue).intValue(); 1440 } 1441 } 1442 SummingAfterAdvice aa = new SummingAfterAdvice(); 1443 Advisor matchesInt = new StaticMethodMatcherPointcutAdvisor(aa) { 1444 public boolean matches(Method m, Class targetClass) { 1445 return m.getReturnType() == int.class; 1446 } 1447 }; 1448 TestBean target = new TestBean(); 1449 ProxyFactory pf = new ProxyFactory(target); 1450 pf.addAdvice(new NopInterceptor()); 1451 pf.addAdvisor(matchesInt); 1452 assertEquals("Advisor was added", matchesInt, pf.getAdvisors()[1]); 1453 ITestBean proxied = (ITestBean) createProxy(pf); 1454 assertEquals(0, aa.sum); 1455 int i1 = 12; 1456 int i2 = 13; 1457 1458 proxied.setAge(i1); 1460 assertEquals(i1, proxied.getAge()); 1461 assertEquals(i1, aa.sum); 1462 proxied.setAge(i2); 1463 assertEquals(i2, proxied.getAge()); 1464 assertEquals(i1 + i2, aa.sum); 1465 assertEquals(i2, proxied.getAge()); 1466 } 1467 1468 public void testAfterReturningAdvisorIsNotInvokedOnException() { 1469 CountingAfterReturningAdvice car = new CountingAfterReturningAdvice(); 1470 TestBean target = new TestBean(); 1471 ProxyFactory pf = new ProxyFactory(target); 1472 pf.addAdvice(new NopInterceptor()); 1473 pf.addAdvice(car); 1474 assertEquals("Advice was wrapped in Advisor and added", car, pf.getAdvisors()[1].getAdvice()); 1475 ITestBean proxied = (ITestBean) createProxy(pf); 1476 assertEquals(0, car.getCalls()); 1477 int age = 10; 1478 proxied.setAge(age); 1479 assertEquals(age, proxied.getAge()); 1480 assertEquals(2, car.getCalls()); 1481 Exception exc = new Exception (); 1482 try { 1484 proxied.exceptional(exc); 1485 fail(); 1486 } 1487 catch (Throwable t) { 1488 assertSame(exc, t); 1489 } 1490 assertEquals(2, car.getCalls()); 1491 } 1492 1493 1494 public void testThrowsAdvisorIsInvoked() throws Throwable { 1495 ThrowsAdviceInterceptorTests.MyThrowsHandler th = new ThrowsAdviceInterceptorTests.MyThrowsHandler(); 1497 Advisor matchesEchoInvocations = new StaticMethodMatcherPointcutAdvisor(th) { 1498 public boolean matches(Method m, Class targetClass) { 1499 return m.getName().startsWith("echo"); 1500 } 1501 }; 1502 1503 ThrowsAdviceInterceptorTests.Echo target = new ThrowsAdviceInterceptorTests.Echo(); 1504 target.setA(16); 1505 ProxyFactory pf = new ProxyFactory(target); 1506 pf.addAdvice(new NopInterceptor()); 1507 pf.addAdvisor(matchesEchoInvocations); 1508 assertEquals("Advisor was added", matchesEchoInvocations, pf.getAdvisors()[1]); 1509 ThrowsAdviceInterceptorTests.IEcho proxied = (ThrowsAdviceInterceptorTests.IEcho) createProxy(pf); 1510 assertEquals(0, th.getCalls()); 1511 assertEquals(target.getA(), proxied.getA()); 1512 assertEquals(0, th.getCalls()); 1513 Exception ex = new Exception (); 1514 try { 1516 proxied.echoException(1, ex); 1517 fail(); 1518 } 1519 catch (Exception caught) { 1520 assertEquals(ex, caught); 1521 } 1522 1523 ex = new ServletException (); 1524 try { 1525 proxied.echoException(1, ex); 1526 fail(); 1527 } 1528 catch (ServletException caught) { 1529 assertEquals(ex, caught); 1530 } 1531 assertEquals(1, th.getCalls("servletException")); 1532 } 1533 1534 public void testAddThrowsAdviceWithoutAdvisor() throws Throwable { 1535 ThrowsAdviceInterceptorTests.MyThrowsHandler th = new ThrowsAdviceInterceptorTests.MyThrowsHandler(); 1537 1538 ThrowsAdviceInterceptorTests.Echo target = new ThrowsAdviceInterceptorTests.Echo(); 1539 target.setA(16); 1540 ProxyFactory pf = new ProxyFactory(target); 1541 pf.addAdvice(new NopInterceptor()); 1542 pf.addAdvice(th); 1543 ThrowsAdviceInterceptorTests.IEcho proxied = (ThrowsAdviceInterceptorTests.IEcho) createProxy(pf); 1544 assertEquals(0, th.getCalls()); 1545 assertEquals(target.getA(), proxied.getA()); 1546 assertEquals(0, th.getCalls()); 1547 Exception ex = new Exception (); 1548 try { 1550 proxied.echoException(1, ex); 1551 fail(); 1552 } 1553 catch (Exception caught) { 1554 assertEquals(ex, caught); 1555 } 1556 1557 ex = new TransactionRequiredException (); 1559 try { 1560 proxied.echoException(1, ex); 1561 fail(); 1562 } 1563 catch (TransactionRequiredException caught) { 1564 assertEquals(ex, caught); 1565 } 1566 assertEquals(1, th.getCalls("remoteException")); 1567 } 1568 1569 1570 private static class CheckMethodInvocationIsSameInAndOutInterceptor implements MethodInterceptor { 1571 1572 public Object invoke(MethodInvocation mi) throws Throwable { 1573 Method m = mi.getMethod(); 1574 Object retval = mi.proceed(); 1575 assertEquals("Method invocation has same method on way back", m, mi.getMethod()); 1576 return retval; 1577 } 1578 } 1579 1580 1581 1584 private static class CheckMethodInvocationViaThreadLocalIsSameInAndOutInterceptor implements MethodInterceptor { 1585 1586 public Object invoke(MethodInvocation mi) throws Throwable { 1587 String task = "get invocation on way IN"; 1588 try { 1589 MethodInvocation current = ExposeInvocationInterceptor.currentInvocation(); 1590 assertEquals(mi, current); 1591 Object retval = mi.proceed(); 1592 task = "get invocation on way OUT"; 1593 assertEquals(current, ExposeInvocationInterceptor.currentInvocation()); 1594 return retval; 1595 } 1596 catch (AspectException ex) { 1597 System.err.println(task + " for " + mi.getMethod()); 1598 ex.printStackTrace(); 1599 throw ex; 1601 } 1602 } 1603 } 1604 1605 1606 1611 private static class ProxyMatcherInterceptor implements MethodInterceptor { 1612 1613 public Object invoke(MethodInvocation mi) throws Throwable { 1614 Object proxy = AopContext.currentProxy(); 1615 Object ret = mi.proceed(); 1616 assertTrue(proxy == AopContext.currentProxy()); 1619 return ret; 1620 } 1621 } 1622 1623 1624 protected static class TestDynamicPointcutAdvice extends DynamicMethodMatcherPointcutAdvisor { 1625 1626 private String pattern; 1627 public int count; 1628 1629 public TestDynamicPointcutAdvice(MethodInterceptor mi, String pattern) { 1630 super(mi); 1631 this.pattern = pattern; 1632 } 1633 1634 public boolean matches(Method m, Class targetClass, Object [] args) { 1635 boolean run = m.getName().indexOf(pattern) != -1; 1636 if (run) ++count; 1637 return run; 1638 } 1639 } 1640 1641 1642 protected static class TestDynamicPointcutForSettersOnly extends TestDynamicPointcutAdvice { 1643 1644 public TestDynamicPointcutForSettersOnly(MethodInterceptor mi, String pattern) { 1645 super(mi, pattern); 1646 } 1647 1648 public boolean matches(Method m, Class clazz) { 1649 return m.getName().startsWith("set"); 1650 } 1651 } 1652 1653 1654 protected static class TestStaticPointcutAdvice extends StaticMethodMatcherPointcutAdvisor { 1655 1656 private String pattern; 1657 private int count; 1658 1659 public TestStaticPointcutAdvice(MethodInterceptor mi, String pattern) { 1660 super(mi); 1661 this.pattern = pattern; 1662 } 1663 public boolean matches(Method m, Class targetClass) { 1664 boolean run = m.getName().indexOf(pattern) != -1; 1665 if (run) ++count; 1666 return run; 1667 } 1668 } 1669 1670 1671 1677 protected static class TrapTargetInterceptor implements MethodInterceptor { 1678 1679 public Object target; 1680 1681 public Object invoke(MethodInvocation invocation) throws Throwable { 1682 this.target = invocation.getThis(); 1683 return invocation.proceed(); 1684 } 1685 } 1686 1687 1688 private static class DummyIntroductionAdviceImpl implements DynamicIntroductionAdvice { 1689 1690 public boolean implementsInterface(Class intf) { 1691 return true; 1692 } 1693 } 1694 1695 1696 public static class OwnSpouse extends TestBean { 1697 1698 public ITestBean getSpouse() { 1699 return this; 1700 } 1701 } 1702 1703 1704 private static class EqualsTestBean extends TestBean { 1705 1706 public ITestBean getSpouse() { 1707 return this; 1708 } 1709 } 1710 1711 1712 public static class AllInstancesAreEqual implements IOther { 1713 1714 public boolean equals(Object o) { 1715 return o instanceof AllInstancesAreEqual; 1716 } 1717 1718 public void absquatulate() { 1719 } 1720 } 1721 1722 1723 public interface INeedsToSeeProxy { 1724 1725 int getCount(); 1726 1727 void incrementViaThis(); 1728 1729 void incrementViaProxy(); 1730 1731 void increment(); 1732 } 1733 1734 1735 public static class NeedsToSeeProxy implements INeedsToSeeProxy { 1736 1737 private int count; 1738 1739 public int getCount() { 1740 return count; 1741 } 1742 1743 public void incrementViaThis() { 1744 this.increment(); 1745 } 1746 1747 public void incrementViaProxy() { 1748 INeedsToSeeProxy thisViaProxy = (INeedsToSeeProxy) AopContext.currentProxy(); 1749 thisViaProxy.increment(); 1750 Advised advised = (Advised) thisViaProxy; 1751 checkAdvised(advised); 1752 } 1753 1754 protected void checkAdvised(Advised advised) { 1755 } 1756 1757 public void increment() { 1758 ++count; 1759 } 1760 } 1761 1762 1763 public static class TargetChecker extends NeedsToSeeProxy { 1764 1765 protected void checkAdvised(Advised advised) { 1766 } 1769 } 1770 1771} 1772 | Popular Tags |