001 /***************************************************************************** 002 * Copyright (C) PicoContainer Organization. All rights reserved. * 003 * ------------------------------------------------------------------------- * 004 * The software in this package is published under the terms of the BSD * 005 * style license a copy of which has been included with this distribution in * 006 * the LICENSE.txt file. * 007 * * 008 * Original code by * 009 *****************************************************************************/ 010 package org.picocontainer.behaviors; 011 012 import static org.junit.Assert.assertEquals; 013 import static org.junit.Assert.assertFalse; 014 import static org.junit.Assert.assertNotNull; 015 import static org.junit.Assert.assertSame; 016 017 import org.junit.Test; 018 import org.picocontainer.DefaultPicoContainer; 019 import org.picocontainer.containers.EmptyPicoContainer; 020 import org.picocontainer.lifecycle.NullLifecycleStrategy; 021 022 public class ThreadCachingTestCase { 023 024 public static class Foo { 025 public Foo(StringBuilder sb) { 026 sb.append("<Foo"); 027 } 028 } 029 030 public static class Bar { 031 private final Foo foo; 032 public Bar(StringBuilder sb, Foo foo) { 033 this.foo = foo; 034 sb.append("<Bar"); 035 } 036 } 037 038 @Test public void testThatForASingleThreadTheBehaviorIsTheSameAsPlainCaching() { 039 040 DefaultPicoContainer parent = new DefaultPicoContainer(new Caching()); 041 DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent); 042 043 parent.addComponent(StringBuilder.class); 044 child.addComponent(Foo.class); 045 046 StringBuilder sb = parent.getComponent(StringBuilder.class); 047 Foo foo = child.getComponent(Foo.class); 048 Foo foo2 = child.getComponent(Foo.class); 049 assertNotNull(foo); 050 assertNotNull(foo2); 051 assertEquals(foo,foo2); 052 assertEquals("<Foo", sb.toString()); 053 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString()); 054 } 055 056 @Test public void testThatTwoThreadsHaveSeparatedCacheValues() { 057 058 final Foo[] foos = new Foo[4]; 059 060 DefaultPicoContainer parent = new DefaultPicoContainer(new Caching()); 061 final DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent); 062 063 parent.addComponent(StringBuilder.class); 064 child.addComponent(Foo.class); 065 066 StringBuilder sb = parent.getComponent(StringBuilder.class); 067 foos[0] = child.getComponent(Foo.class); 068 069 Thread thread = new Thread() { 070 public void run() { 071 foos[1] = child.getComponent(Foo.class); 072 foos[3] = child.getComponent(Foo.class); 073 } 074 }; 075 thread.start(); 076 foos[2] = child.getComponent(Foo.class); 077 try { 078 Thread.sleep(100); 079 } catch (InterruptedException e) { 080 } 081 082 assertNotNull(foos[0]); 083 assertNotNull(foos[1]); 084 assertNotNull(foos[2]); 085 assertNotNull(foos[3]); 086 assertSame(foos[0],foos[2]); 087 assertEquals(foos[1],foos[3]); 088 assertFalse(foos[0] == foos[1]); 089 assertEquals("<Foo<Foo", sb.toString()); 090 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString()); 091 } 092 093 @Test public void testThatTwoThreadsHaveSeparatedCacheValuesForThreeScopeScenario() { 094 095 final Foo[] foos = new Foo[4]; 096 final Bar[] bars = new Bar[4]; 097 098 DefaultPicoContainer appScope = new DefaultPicoContainer(new Caching()); 099 final DefaultPicoContainer sessionScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), appScope); 100 final DefaultPicoContainer requestScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), sessionScope); 101 102 appScope.addComponent(StringBuilder.class); 103 sessionScope.addComponent(Foo.class); 104 requestScope.addComponent(Bar.class); 105 106 StringBuilder sb = appScope.getComponent(StringBuilder.class); 107 foos[0] = sessionScope.getComponent(Foo.class); 108 bars[0] = requestScope.getComponent(Bar.class); 109 110 Thread thread = new Thread() { 111 public void run() { 112 foos[1] = sessionScope.getComponent(Foo.class); 113 bars[1] = requestScope.getComponent(Bar.class); 114 foos[3] = sessionScope.getComponent(Foo.class); 115 bars[3] = requestScope.getComponent(Bar.class); 116 } 117 }; 118 thread.start(); 119 foos[2] = sessionScope.getComponent(Foo.class); 120 bars[2] = requestScope.getComponent(Bar.class); 121 try { 122 Thread.sleep(100); 123 } catch (InterruptedException e) { 124 } 125 126 assertSame(bars[0],bars[2]); 127 assertEquals(bars[1],bars[3]); 128 assertFalse(bars[0] == bars[1]); 129 assertSame(bars[0].foo,foos[0]); 130 assertSame(bars[1].foo,foos[1]); 131 assertSame(bars[2].foo,foos[2]); 132 assertSame(bars[3].foo,foos[3]); 133 assertEquals("<Foo<Bar<Foo<Bar", sb.toString()); 134 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", sessionScope.getComponentAdapter(Foo.class).toString()); 135 } 136 137 138 }