KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > framework > ProxyFactoryBeanTests


1 /*
2  * Copyright 2002-2005 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.aop.framework;
18
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Proxy JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.List JavaDoc;
23
24 import javax.servlet.ServletException JavaDoc;
25
26 import junit.framework.TestCase;
27 import org.aopalliance.aop.Advice;
28 import org.aopalliance.intercept.MethodInterceptor;
29 import org.aopalliance.intercept.MethodInvocation;
30
31 import org.springframework.aop.ClassFilter;
32 import org.springframework.aop.IntroductionAdvisor;
33 import org.springframework.aop.IntroductionInterceptor;
34 import org.springframework.aop.framework.adapter.ThrowsAdviceInterceptorTests;
35 import org.springframework.aop.interceptor.DebugInterceptor;
36 import org.springframework.aop.interceptor.NopInterceptor;
37 import org.springframework.aop.interceptor.SideEffectBean;
38 import org.springframework.aop.support.AopUtils;
39 import org.springframework.aop.support.DefaultIntroductionAdvisor;
40 import org.springframework.aop.support.DynamicMethodMatcherPointcutAdvisor;
41 import org.springframework.beans.ITestBean;
42 import org.springframework.beans.Person;
43 import org.springframework.beans.TestBean;
44 import org.springframework.beans.factory.BeanCreationException;
45 import org.springframework.beans.factory.BeanFactory;
46 import org.springframework.beans.factory.FactoryBean;
47 import org.springframework.beans.factory.ListableBeanFactory;
48 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
49 import org.springframework.beans.factory.support.RootBeanDefinition;
50 import org.springframework.beans.factory.xml.XmlBeanFactory;
51 import org.springframework.context.ApplicationListener;
52 import org.springframework.context.event.ConsoleListener;
53 import org.springframework.core.io.ClassPathResource;
54 import org.springframework.util.SerializationTestUtils;
55
56 /**
57  * Test cases for AOP FactoryBean, using XML bean factory.
58  * Note that this FactoryBean will work in any bean factory implementation.
59  *
60  * @author Rod Johnson
61  * @since 13.03.2003
62  */

63 public class ProxyFactoryBeanTests extends TestCase {
64     
65     private BeanFactory factory;
66
67     protected void setUp() throws Exception JavaDoc {
68         DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
69         parent.registerBeanDefinition("target2", new RootBeanDefinition(ConsoleListener.class));
70         this.factory = new XmlBeanFactory(new ClassPathResource("proxyFactoryTests.xml", getClass()), parent);
71     }
72
73     public void testIsDynamicProxy() {
74         ITestBean test1 = (ITestBean) factory.getBean("test1");
75         assertTrue("test1 is a dynamic proxy", Proxy.isProxyClass(test1.getClass()));
76     }
77     
78     /**
79      * Test that it's forbidden to specify TargetSource in both
80      * interceptor chain and targetSource property.
81      */

82     public void testDoubleTargetSourcesAreRejected() {
83         testDoubleTargetSourceIsRejected("doubleTarget");
84         // Now with conversion from arbitrary bean to a TargetSource
85
testDoubleTargetSourceIsRejected("arbitraryTarget");
86     }
87     
88     private void testDoubleTargetSourceIsRejected(String JavaDoc name) {
89         try {
90             BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryDoubleTargetSourceTests.xml", getClass()));
91             ITestBean tb = (ITestBean) bf.getBean(name);
92             //assertEquals("Adam", tb.getName());
93
fail("Should not allow TargetSource to be specified in interceptorNames as well as targetSource property");
94         }
95         catch (BeanCreationException ex) {
96             // Root cause of the problem must be an AOP exception
97
AopConfigException aex = (AopConfigException) ex.getCause();
98             assertTrue(aex.getMessage().indexOf("TargetSource") != -1);
99         }
100     }
101     
102     public void testTargetSourceNotAtEndOfInterceptorNamesIsRejected() {
103         try {
104             BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTargetSourceNotLastTests.xml", getClass()));
105             bf.getBean("targetSourceNotLast");
106             fail("TargetSource or non-advised object must be last in interceptorNames");
107         }
108         catch (BeanCreationException ex) {
109             // Root cause of the problem must be an AOP exception
110
AopConfigException aex = (AopConfigException) ex.getCause();
111             assertTrue(aex.getMessage().indexOf("interceptorNames") != -1);
112         }
113     }
114     
115     public void testGetObjectTypeWithDirectTarget() {
116         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTargetSourceTests.xml", getClass()));
117         
118         // We have a counting before advice here
119
CountingBeforeAdvice cba = (CountingBeforeAdvice) bf.getBean("countingBeforeAdvice");
120         assertEquals(0, cba.getCalls());
121     
122         ITestBean tb = (ITestBean) bf.getBean("directTarget");
123         assertTrue(tb.getName().equals("Adam"));
124         assertEquals(1, cba.getCalls());
125         
126         ProxyFactoryBean pfb = (ProxyFactoryBean) bf.getBean("&directTarget");
127         assertTrue("Has correct object type", TestBean.class.isAssignableFrom(pfb.getObjectType()));
128     }
129     
130     public void testGetObjectTypeWithTargetViaTargetSource() {
131         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTargetSourceTests.xml", getClass()));
132         ITestBean tb = (ITestBean) bf.getBean("viaTargetSource");
133         assertTrue(tb.getName().equals("Adam"));
134         ProxyFactoryBean pfb = (ProxyFactoryBean) bf.getBean("&viaTargetSource");
135         assertTrue("Has correct object type", TestBean.class.isAssignableFrom(pfb.getObjectType()));
136     }
137     
138     public void testGetObjectTypeWithNoTargetOrTargetSource() {
139         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTargetSourceTests.xml", getClass()));
140
141         ITestBean tb = (ITestBean) bf.getBean("noTarget");
142         try {
143             tb.getName();
144             fail();
145         }
146         catch (UnsupportedOperationException JavaDoc ex) {
147             assertEquals("getName", ex.getMessage());
148         }
149         FactoryBean pfb = (ProxyFactoryBean) bf.getBean("&noTarget");
150         assertTrue(ITestBean.class.isAssignableFrom(pfb.getObjectType()));
151     }
152     
153     /**
154      * The instances are equal, but do not have object identity.
155      * Interceptors and interfaces and the target are the same.
156      */

157     public void testSingletonInstancesAreEqual() {
158         ITestBean test1 = (ITestBean) factory.getBean("test1");
159         ITestBean test1_1 = (ITestBean) factory.getBean("test1");
160         //assertTrue("Singleton instances ==", test1 == test1_1);
161
assertEquals("Singleton instances ==", test1, test1_1);
162         test1.setAge(25);
163         assertEquals(test1.getAge(), test1_1.getAge());
164         test1.setAge(250);
165         assertEquals(test1.getAge(), test1_1.getAge());
166         Advised pc1 = (Advised) test1;
167         Advised pc2 = (Advised) test1_1;
168         assertEquals(pc1.getAdvisors(), pc2.getAdvisors());
169         int oldLength = pc1.getAdvisors().length;
170         NopInterceptor di = new NopInterceptor();
171         pc1.addAdvice(1, di);
172         assertEquals(pc1.getAdvisors(), pc2.getAdvisors());
173         assertEquals("Now have one more advisor", oldLength + 1, pc2.getAdvisors().length);
174         assertEquals(di.getCount(), 0);
175         test1.setAge(5);
176         assertEquals(test1_1.getAge(), test1.getAge());
177         assertEquals(di.getCount(), 3);
178     }
179     
180     
181     public void testPrototypeInstancesAreNotEqual() {
182         ITestBean test2 = (ITestBean) factory.getBean("prototype");
183         ITestBean test2_1 = (ITestBean) factory.getBean("prototype");
184         assertTrue("Prototype instances !=", test2 != test2_1);
185         assertTrue("Prototype instances equal", test2.equals(test2_1));
186     }
187     
188     
189     /**
190      * Uses its own bean factory XML for clarity
191      * @param beanName name of the ProxyFactoryBean definition that should
192      * be a prototype
193      */

194     private Object JavaDoc testPrototypeInstancesAreIndependent(String JavaDoc beanName) {
195         // Initial count value set in bean factory XML
196
int INITIAL_COUNT = 10;
197         
198         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("prototypeTests.xml", getClass()));
199         
200         // Check it works without AOP
201
SideEffectBean raw = (SideEffectBean) bf.getBean("prototypeTarget");
202         assertEquals(INITIAL_COUNT, raw.getCount() );
203         raw.doWork();
204         assertEquals(INITIAL_COUNT+1, raw.getCount() );
205         raw = (SideEffectBean) bf.getBean("prototypeTarget");
206         assertEquals(INITIAL_COUNT, raw.getCount() );
207         
208         // Now try with advised instances
209
SideEffectBean prototype2FirstInstance = (SideEffectBean) bf.getBean(beanName);
210         assertEquals(INITIAL_COUNT, prototype2FirstInstance.getCount() );
211         prototype2FirstInstance.doWork();
212         assertEquals(INITIAL_COUNT + 1, prototype2FirstInstance.getCount() );
213
214         SideEffectBean prototype2SecondInstance = (SideEffectBean) bf.getBean(beanName);
215         assertFalse("Prototypes are not ==", prototype2FirstInstance == prototype2SecondInstance);
216         assertEquals(INITIAL_COUNT, prototype2SecondInstance.getCount() );
217         assertEquals(INITIAL_COUNT + 1, prototype2FirstInstance.getCount() );
218         
219         return prototype2FirstInstance;
220     }
221     
222     public void testCglibPrototypeInstancesAreIndependent() {
223         Object JavaDoc prototype = testPrototypeInstancesAreIndependent("cglibPrototype");
224         assertTrue("It's a cglib proxy", AopUtils.isCglibProxy(prototype));
225         assertFalse("It's not a dynamic proxy", AopUtils.isJdkDynamicProxy(prototype));
226     }
227     
228     public void testPrototypeInstancesAreIndependentWithTargetName() {
229         Object JavaDoc prototype = testPrototypeInstancesAreIndependent("prototype");
230         //assertTrue("It's a dynamic proxy", AopUtils.isJdkDynamicProxy(prototype));
231
}
232     
233     /**
234      * Test invoker is automatically added to manipulate target
235      */

236     public void testAutoInvoker() {
237         String JavaDoc name = "Hieronymous";
238         TestBean target = (TestBean) factory.getBean("test");
239         target.setName(name);
240         ITestBean autoInvoker = (ITestBean) factory.getBean("autoInvoker");
241         assertTrue(autoInvoker.getName().equals(name));
242     }
243
244     public void testCanGetFactoryReferenceAndManipulate() {
245         ProxyFactoryBean config = (ProxyFactoryBean) factory.getBean("&test1");
246         assertEquals("Have one advisors", 1, config.getAdvisors().length);
247         
248         ITestBean tb = (ITestBean) factory.getBean("test1");
249         // no exception
250
tb.hashCode();
251         
252         final Exception JavaDoc ex = new UnsupportedOperationException JavaDoc("invoke");
253         // Add evil interceptor to head of list
254
config.addAdvice(0, new MethodInterceptor() {
255             public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
256                 throw ex;
257             }
258         });
259         assertEquals("Have correct advisor count", 2, config.getAdvisors().length);
260         
261         tb = (ITestBean) factory.getBean("test1");
262         try {
263             // Will fail now
264
tb.toString();
265             fail("Evil interceptor added programmatically should fail all method calls");
266         }
267         catch (Exception JavaDoc thrown) {
268             assertTrue(thrown == ex);
269         }
270     }
271     
272     public static class DependsOnITestBean {
273         public final ITestBean tb;
274         public DependsOnITestBean(ITestBean tb) {
275             this.tb = tb;
276         }
277     }
278     
279     /**
280      * Test that inner bean for target means that we can use
281      * autowire without ambiguity from target and proxy
282      */

283     public void testTargetAsInnerBean() {
284         ListableBeanFactory bf = new XmlBeanFactory(new ClassPathResource("innerBeanTarget.xml", getClass()));
285         ITestBean itb = (ITestBean) bf.getBean("testBean");
286         assertEquals("innerBeanTarget", itb.getName());
287         assertEquals("Only have proxy and interceptor: no target", 3, bf.getBeanDefinitionCount());
288         DependsOnITestBean doit = (DependsOnITestBean) bf.getBean("autowireCheck");
289         assertSame(itb, doit.tb);
290     }
291     
292     /**
293      * Should see effect immediately on behavior.
294      */

295     public void testCanAddAndRemoveAspectInterfacesOnSingleton() {
296         try {
297             TimeStamped ts = (TimeStamped) factory.getBean("test1");
298             fail("Shouldn't implement TimeStamped before manipulation");
299         }
300         catch (ClassCastException JavaDoc ex) {
301         }
302     
303         ProxyFactoryBean config = (ProxyFactoryBean) factory.getBean("&test1");
304         long time = 666L;
305         TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor();
306         ti.setTime(time);
307         
308         // add to front of interceptor chain
309
int oldCount = config.getAdvisors().length;
310         config.addAdvisor(0, new DefaultIntroductionAdvisor(ti, TimeStamped.class));
311         
312         assertTrue(config.getAdvisors().length == oldCount + 1);
313     
314         TimeStamped ts = (TimeStamped) factory.getBean("test1");
315         assertTrue(ts.getTimeStamp() == time);
316     
317         // Can remove
318
config.removeAdvice(ti);
319
320         assertTrue(config.getAdvisors().length == oldCount);
321     
322         try {
323             // Existing reference will fail
324
ts.getTimeStamp();
325             fail("Existing object won't implement this interface any more");
326         }
327         catch (RuntimeException JavaDoc ex) {
328         }
329
330     
331         try {
332             ts = (TimeStamped) factory.getBean("test1");
333             fail("Should no longer implement TimeStamped");
334         }
335         catch (ClassCastException JavaDoc ex) {
336         }
337     
338         // Now check non-effect of removing interceptor that isn't there
339
config.removeAdvice(new DebugInterceptor());
340     
341         assertTrue(config.getAdvisors().length == oldCount);
342     
343         ITestBean it = (ITestBean) ts;
344         DebugInterceptor debugInterceptor = new DebugInterceptor();
345         config.addAdvice(0, debugInterceptor);
346         it.getSpouse();
347         assertEquals(1, debugInterceptor.getCount());
348         config.removeAdvice(debugInterceptor);
349         it.getSpouse();
350         // not invoked again
351
assertTrue(debugInterceptor.getCount() == 1);
352     }
353
354     /**
355      * Try adding and removing interfaces and interceptors on prototype.
356      * Changes will only affect future references obtained from the factory.
357      * Each instance will be independent.
358      */

359     public void testCanAddAndRemoveAspectInterfacesOnPrototype() {
360         try {
361             TimeStamped ts = (TimeStamped) factory.getBean("test2");
362             fail("Shouldn't implement TimeStamped before manipulation");
363         }
364         catch (ClassCastException JavaDoc ex) {
365         }
366         
367         ProxyFactoryBean config = (ProxyFactoryBean) factory.getBean("&test2");
368         long time = 666L;
369         TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor();
370         ti.setTime(time);
371         // Add to head of interceptor chain
372
int oldCount = config.getAdvisors().length;
373         config.addAdvisor(0, new DefaultIntroductionAdvisor(ti, TimeStamped.class));
374         assertTrue(config.getAdvisors().length == oldCount + 1);
375         
376         TimeStamped ts = (TimeStamped) factory.getBean("test2");
377         assertEquals(time, ts.getTimeStamp());
378         
379         // Can remove
380
config.removeAdvice(ti);
381         assertTrue(config.getAdvisors().length == oldCount);
382         
383         // Check no change on existing object reference
384
assertTrue(ts.getTimeStamp() == time);
385         
386         try {
387             ts = (TimeStamped) factory.getBean("test2");
388             fail("Should no longer implement TimeStamped");
389         }
390         catch (ClassCastException JavaDoc ex) {
391         }
392         
393         // Now check non-effect of removing interceptor that isn't there
394
config.removeAdvice(new DebugInterceptor());
395         assertTrue(config.getAdvisors().length == oldCount);
396         
397         ITestBean it = (ITestBean) ts;
398         DebugInterceptor debugInterceptor = new DebugInterceptor();
399         config.addAdvice(0, debugInterceptor);
400         it.getSpouse();
401         // Won't affect existing reference
402
assertTrue(debugInterceptor.getCount() == 0);
403         it = (ITestBean) factory.getBean("test2");
404         it.getSpouse();
405         assertEquals(1, debugInterceptor.getCount());
406         config.removeAdvice(debugInterceptor);
407         it.getSpouse();
408         
409         // Still invoked wiht old reference
410
assertEquals(2, debugInterceptor.getCount());
411         
412         // not invoked with new object
413
it = (ITestBean) factory.getBean("test2");
414         it.getSpouse();
415         assertEquals(2, debugInterceptor.getCount());
416         
417         // Our own timestamped reference should still work
418
assertEquals(time, ts.getTimeStamp());
419     }
420
421     /**
422      * Note that we can't add or remove interfaces without reconfiguring the
423      * singleton.
424      * TODO address this?
425      */

426     public void testCanAddAndRemoveAspectInterfacesOnSingletonByCasting() {
427         ITestBean it = (ITestBean) factory.getBean("test1");
428         Advised pc = (Advised) it;
429         it.getAge();
430         NopInterceptor di = new NopInterceptor();
431         pc.addAdvice(0, di);
432         assertEquals(0, di.getCount());
433         it.setAge(25);
434         assertEquals(25, it.getAge());
435         assertEquals(2, di.getCount());
436     }
437
438     public void testMethodPointcuts() {
439         ITestBean tb = (ITestBean) factory.getBean("pointcuts");
440         PointcutForVoid.reset();
441         assertTrue("No methods intercepted", PointcutForVoid.methodNames.isEmpty());
442         tb.getAge();
443         assertTrue("Not void: shouldn't have intercepted", PointcutForVoid.methodNames.isEmpty());
444         tb.setAge(1);
445         tb.getAge();
446         tb.setName("Tristan");
447         tb.toString();
448         assertEquals("Recorded wrong number of invocations", 2, PointcutForVoid.methodNames.size());
449         assertTrue(PointcutForVoid.methodNames.get(0).equals("setAge"));
450         assertTrue(PointcutForVoid.methodNames.get(1).equals("setName"));
451     }
452     
453     public void testCanAddThrowsAdviceWithoutAdvisor() throws Throwable JavaDoc {
454         BeanFactory f = new XmlBeanFactory(new ClassPathResource("throwsAdvice.xml", getClass()));
455         ThrowsAdviceInterceptorTests.MyThrowsHandler th = (ThrowsAdviceInterceptorTests.MyThrowsHandler) f.getBean("throwsAdvice");
456         CountingBeforeAdvice cba = (CountingBeforeAdvice) f.getBean("countingBeforeAdvice");
457         assertEquals(0, cba.getCalls());
458         assertEquals(0, th.getCalls());
459         ThrowsAdviceInterceptorTests.IEcho echo = (ThrowsAdviceInterceptorTests.IEcho) f.getBean("throwsAdvised");
460         int i = 12;
461         echo.setA(i);
462         assertEquals(i, echo.getA());
463         assertEquals(2, cba.getCalls());
464         assertEquals(0, th.getCalls());
465         Exception JavaDoc expected = new Exception JavaDoc();
466         try {
467             echo.echoException(1, expected);
468             fail();
469         }
470         catch (Exception JavaDoc ex) {
471             assertEquals(expected, ex);
472         }
473         // No throws handler method: count should still be 0
474
assertEquals(0, th.getCalls());
475         
476         // Handler knows how to handle this exception
477
expected = new ServletException JavaDoc();
478         try {
479             echo.echoException(1, expected);
480             fail();
481         }
482         catch (ServletException JavaDoc ex) {
483             assertEquals(expected, ex);
484         }
485         // One match
486
assertEquals(1, th.getCalls("servletException"));
487     }
488
489     // These two fail the whole bean factory
490
// TODO put in sep file to check quality of error message
491
/*
492     public void testNoInterceptorNamesWithoutTarget() {
493         try {
494             ITestBean tb = (ITestBean) factory.getBean("noInterceptorNamesWithoutTarget");
495             fail("Should require interceptor names");
496         }
497         catch (AopConfigException ex) {
498             // Ok
499         }
500     }
501     
502     public void testNoInterceptorNamesWithTarget() {
503         ITestBean tb = (ITestBean) factory.getBean("noInterceptorNamesWithoutTarget");
504     }
505     */

506
507     public void testEmptyInterceptorNames() {
508         XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("invalidProxyFactory.xml", getClass()));
509         try {
510             ITestBean tb = (ITestBean) factory.getBean("emptyInterceptorNames");
511             fail("Interceptor names cannot be empty");
512         }
513         catch (BeanCreationException ex) {
514             // Ok
515
}
516     }
517
518     /**
519      * Globals must be followed by a target.
520      */

521     public void testGlobalsWithoutTarget() {
522         XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("invalidProxyFactory.xml", getClass()));
523         try {
524             ITestBean tb = (ITestBean) factory.getBean("globalsWithoutTarget");
525             fail("Should require target name");
526         }
527         catch (BeanCreationException ex) {
528             assertTrue(ex.getCause() instanceof AopConfigException);
529         }
530     }
531
532     /**
533      * Checks that globals get invoked,
534      * and that they can add aspect interfaces unavailable
535      * to other beans. These interfaces don't need
536      * to be included in proxiedInterface [].
537      */

538     public void testGlobalsCanAddAspectInterfaces() {
539         AddedGlobalInterface agi = (AddedGlobalInterface) factory.getBean("autoInvoker");
540         assertTrue(agi.globalsAdded() == -1);
541         
542         ProxyFactoryBean pfb = (ProxyFactoryBean) factory.getBean("&validGlobals");
543         // 2 globals + 2 explicit
544
assertEquals("Have 2 globals and 2 explicit advisors", 3, pfb.getAdvisors().length);
545         
546         ApplicationListener l = (ApplicationListener) factory.getBean("validGlobals");
547         agi = (AddedGlobalInterface) l;
548         assertTrue(agi.globalsAdded() == -1);
549         
550         try {
551             agi = (AddedGlobalInterface) factory.getBean("test1");
552             fail("Aspect interface should't be implemeneted without globals");
553         }
554         catch (ClassCastException JavaDoc ex) {
555         }
556     }
557     
558     public void testSerializableSingletonProxy() throws Exception JavaDoc {
559         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("serializationTests.xml", getClass()));
560         Person p = (Person) bf.getBean("serializableSingleton");
561         assertSame("Should be a Singleton", p, bf.getBean("serializableSingleton"));
562         Person p2 = (Person) SerializationTestUtils.serializeAndDeserialize(p);
563         assertEquals(p, p2);
564         assertNotSame(p, p2);
565         assertEquals("serializableSingleton", p2.getName());
566         
567         // Add unserializable advice
568
Advice nop = new NopInterceptor();
569         ((Advised) p).addAdvice(nop);
570         // Check it still works
571
assertEquals(p2.getName(), p2.getName());
572         assertFalse("Not serializable because an interceptor isn't serializable", SerializationTestUtils.isSerializable(p));
573         
574         // Remove offending interceptor...
575
assertTrue(((Advised) p).removeAdvice(nop));
576         assertTrue("Serializable again because offending interceptor was removed", SerializationTestUtils.isSerializable(p));
577     }
578     
579     public void testSerializablePrototypeProxy() throws Exception JavaDoc {
580         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("serializationTests.xml", getClass()));
581         Person p = (Person) bf.getBean("serializablePrototype");
582         assertNotSame("Should not be a Singleton", p, bf.getBean("serializablePrototype"));
583         Person p2 = (Person) SerializationTestUtils.serializeAndDeserialize(p);
584         assertEquals(p, p2);
585         assertNotSame(p, p2);
586         assertEquals("serializablePrototype", p2.getName());
587     }
588     
589     public void testProxyNotSerializableBecauseOfAdvice() throws Exception JavaDoc {
590         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("serializationTests.xml", getClass()));
591         Person p = (Person) bf.getBean("interceptorNotSerializableSingleton");
592         assertFalse("Not serializable because an interceptor isn't serializable", SerializationTestUtils.isSerializable(p));
593     }
594
595     public void testPrototypeAdvisor() {
596         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTests.xml", getClass()));
597
598         ITestBean bean1 = (ITestBean) bf.getBean("prototypeTestBeanProxy");
599         ITestBean bean2 = (ITestBean) bf.getBean("prototypeTestBeanProxy");
600
601         bean1.setAge(3);
602         bean2.setAge(4);
603
604         assertEquals(3, bean1.getAge());
605         assertEquals(4, bean2.getAge());
606
607         ((Lockable) bean1).lock();
608
609         try {
610             bean1.setAge(5);
611             fail("expected LockedException");
612         }
613         catch (LockedException ex) {
614             // expected
615
}
616
617         try {
618             bean2.setAge(6);
619         }
620         catch (LockedException ex) {
621             fail("did not expect LockedException");
622         }
623     }
624
625     public void testPrototypeInterceptorSingletonTarget() {
626         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryTests.xml", getClass()));
627
628         ITestBean bean1 = (ITestBean) bf.getBean("prototypeTestBeanProxySingletonTarget");
629         ITestBean bean2 = (ITestBean) bf.getBean("prototypeTestBeanProxySingletonTarget");
630
631         bean1.setAge(1);
632         bean2.setAge(2);
633
634         assertEquals(2, bean1.getAge());
635
636         ((Lockable) bean1).lock();
637
638         try {
639             bean1.setAge(5);
640             fail("expected LockedException");
641         }
642         catch (LockedException ex) {
643             // expected
644
}
645
646         try {
647             bean2.setAge(6);
648         }
649         catch (LockedException ex) {
650             fail("did not expect LockedException");
651         }
652     }
653     
654     /**
655      * Simple test of a ProxyFactoryBean that has an inner bean as target that specifies autowiring.
656      * Checks for correct use of getType() by bean factory.
657      */

658     public void testInnerBeanTargetUsingAutowiring() {
659         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("proxyFactoryBeanAutowiringTests.xml", getClass()));
660         bf.getBean("testBean");
661     }
662     
663     public void testFrozenFactoryBean() {
664         BeanFactory bf = new XmlBeanFactory(new ClassPathResource("frozenProxyFactoryBean.xml", getClass()));
665         
666         Advised advised = (Advised)bf.getBean("frozen");
667         assertTrue("The proxy should be frozen", advised.isFrozen());
668     }
669
670     /**
671      * Fires only on void methods. Saves list of methods intercepted.
672      */

673     public static class PointcutForVoid extends DynamicMethodMatcherPointcutAdvisor {
674         
675         public static List JavaDoc methodNames = new LinkedList JavaDoc();
676         
677         public static void reset() {
678             methodNames.clear();
679         }
680         
681         public PointcutForVoid() {
682             super( new MethodInterceptor() {
683                 public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
684                     methodNames.add(invocation.getMethod().getName());
685                     return invocation.proceed();
686                 }
687             });
688         }
689         
690         /** Should fire only if it returns null */
691         public boolean matches(Method JavaDoc m, Class JavaDoc targetClass, Object JavaDoc[] args) {//, AttributeRegistry attributeRegistry) {
692
//System.out.println(mi.getMethod().getReturnType());
693
return m.getReturnType() == Void.TYPE;
694         }
695     }
696
697
698     /**
699      * Aspect interface
700      */

701     public interface AddedGlobalInterface {
702         int globalsAdded();
703     }
704
705
706     /**
707      * Use as a global interceptor. Checks that
708      * global interceptors can add aspect interfaces.
709      * NB: Add only via global interceptors in XML file.
710      */

711     public static class GlobalAspectInterfaceInterceptor implements IntroductionInterceptor {
712
713         public boolean implementsInterface(Class JavaDoc intf) {
714             return intf.equals(AddedGlobalInterface.class);
715         }
716
717         public Object JavaDoc invoke(MethodInvocation mi) throws Throwable JavaDoc {
718             if (mi.getMethod().getDeclaringClass().equals(AddedGlobalInterface.class)) {
719                 return new Integer JavaDoc(-1);
720             }
721             return mi.proceed();
722         }
723     }
724
725
726     public static class GlobalIntroductionAdvice implements IntroductionAdvisor {
727         
728         private IntroductionInterceptor gi = new GlobalAspectInterfaceInterceptor();
729
730         public ClassFilter getClassFilter() {
731             return ClassFilter.TRUE;
732         }
733
734         public Advice getAdvice() {
735             return this.gi;
736         }
737
738         public Class JavaDoc[] getInterfaces() {
739             return new Class JavaDoc[] { AddedGlobalInterface.class };
740         }
741
742         public boolean isPerInstance() {
743             return false;
744         }
745         
746         public void validateInterfaces() {
747         }
748     }
749     
750 }
751
Popular Tags