⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractaopproxytests.java

📁 Java/J2EE application framework based on [Expert One-on-One J2EE Design and Development] by Rod John
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
		}
	}
	
	/**
	 * Check that the introduction advice isn't allowed to introduce interfaces
	 * that are unsupported by the IntroductionInterceptor
	 * @throws Throwable
	 */
	public void testCannotAddIntroductionAdviceWithUnimplementedInterface() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		try {
			pc.addAdvisor(0, new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor(), ITestBean.class));
			fail("Shouldn't be able to add introduction advice introducing an unimplemented interface");
		}
		catch (IllegalArgumentException ex) {
			//assertTrue(ex.getMessage().indexOf("ntroduction") > -1);
		}
		// Check it still works: proxy factory state shouldn't have been corrupted
		ITestBean proxied = (ITestBean) createProxy(pc);
		assertEquals(target.getAge(), proxied.getAge());
	}
	
	/**
	 * Note that an introduction can't throw an unexpected checked exception, 
	 * as it's constained by the interface
	 * @throws Throwable
	 */
	public void testIntroductionThrowsUncheckedException() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		
		class MyDi extends DelegatingIntroductionInterceptor implements TimeStamped {
			/**
			 * @see org.springframework.aop.framework.TimeStamped#getTimeStamp()
			 */
			public long getTimeStamp() {
				throw new UnsupportedOperationException();
			}
		}
		pc.addAdvisor(new DefaultIntroductionAdvisor(new MyDi()));
		
		TimeStamped ts = (TimeStamped) createProxy(pc);
		try {
			ts.getTimeStamp();
			fail("Should throw UnsupportedOperationException");
		}
		catch (UnsupportedOperationException ex) {
		}
	}
	
	/**
	 * Should only be able to introduce interfaces, not classes
	 * @throws Throwable
	 */
	public void testCannotAddIntroductionAdviceToIntroduceClass() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		try {
			pc.addAdvisor(0, new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor(), TestBean.class));
			fail("Shouldn't be able to add introduction advice that introduces a class, rather than an interface");
		}
		catch (IllegalArgumentException ex) {
			assertTrue(ex.getMessage().indexOf("interface") > -1);
		}
		// Check it still works: proxy factory state shouldn't have been corrupted
		ITestBean proxied = (ITestBean) createProxy(pc);
		assertEquals(target.getAge(), proxied.getAge());
	}
	
	public void testCannotAddInterceptorWhenFrozen() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		assertFalse(pc.isFrozen());
		pc.addAdvice(new NopInterceptor());
		ITestBean proxied = (ITestBean) createProxy(pc);
		pc.setFrozen(true);
		try {
			pc.addAdvice(0, new NopInterceptor());
			fail("Shouldn't be able to add interceptor when frozen");
		}
		catch (AopConfigException ex) {
			assertTrue(ex.getMessage().indexOf("frozen") > -1);
		}
		// Check it still works: proxy factory state shouldn't have been corrupted
		assertEquals(target.getAge(), proxied.getAge());
		assertEquals(1, ((Advised) proxied).getAdvisors().length);
	}
	
	/**
	 * Check that casting to Advised can't get around advice freeze
	 * @throws Throwable
	 */
	public void testCannotAddAdvisorWhenFrozenUsingCast() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		assertFalse(pc.isFrozen());
		pc.addAdvice(new NopInterceptor());
		ITestBean proxied = (ITestBean) createProxy(pc);
		pc.setFrozen(true);
		Advised advised = (Advised) proxied;
		
		assertTrue(pc.isFrozen());
		try {
			advised.addAdvisor(new DefaultPointcutAdvisor(new NopInterceptor()));
			fail("Shouldn't be able to add Advisor when frozen");
		}
		catch (AopConfigException ex) {
			assertTrue(ex.getMessage().indexOf("frozen") > -1);
		}
		// Check it still works: proxy factory state shouldn't have been corrupted
		assertEquals(target.getAge(), proxied.getAge());
		assertEquals(1, advised.getAdvisors().length);
	}
	
	public void testCannotRemoveAdvisorWhenFrozen() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		ProxyFactory pc = new ProxyFactory(target);
		assertFalse(pc.isFrozen());
		pc.addAdvice(new NopInterceptor());
		ITestBean proxied = (ITestBean) createProxy(pc);
		pc.setFrozen(true);
		Advised advised = (Advised) proxied;
	
		assertTrue(pc.isFrozen());
		try {
			advised.removeAdvisor(0);
			fail("Shouldn't be able to remove Advisor when frozen");
		}
		catch (AopConfigException ex) {
			assertTrue(ex.getMessage().indexOf("frozen") > -1);
		}
		// Didn't get removed
		assertEquals(1, advised.getAdvisors().length);
		pc.setFrozen(false);
		// Can now remove it
		advised.removeAdvisor(0);
		// Check it still works: proxy factory state shouldn't have been corrupted
		assertEquals(target.getAge(), proxied.getAge());
		assertEquals(0, advised.getAdvisors().length);
	}
	
	public void testUseAsHashKey() {
		TestBean target1 = new TestBean();
		ProxyFactory pf1 = new ProxyFactory(target1);
		pf1.addAdvice(new NopInterceptor());
		ITestBean proxy1 = (ITestBean) createProxy(pf1);
		
		TestBean target2 = new TestBean();
		ProxyFactory pf2 = new ProxyFactory(target2);
		pf2.addAdvisor(new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor()));
		ITestBean proxy2 = (ITestBean) createProxy(pf2);
		
		HashMap h = new HashMap();
		Object value1 = new Object();
		Object value2 = new Object();
		assertNull(h.get(proxy1));
		h.put(proxy1, value1);
		h.put(proxy2, value2);
		assertEquals(h.get(proxy1), value1);
		assertEquals(h.get(proxy2), value2);
	}
	
	/**
	 * Check that the string is informative.
	 *
	 */
	public void testProxyConfigString() {
		TestBean target = new TestBean();
		ProxyFactory pc = new ProxyFactory(target);
		pc.setInterfaces(new Class[] { ITestBean.class } );
		pc.addAdvice(new NopInterceptor());
		MethodBeforeAdvice mba = new CountingBeforeAdvice();
		Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut(), mba);
		pc.addAdvisor(advisor);
		ITestBean proxied = (ITestBean) createProxy(pc);
		
		String proxyConfigString = ((Advised) proxied).toProxyConfigString();
		System.err.println(proxyConfigString);
		assertTrue(proxyConfigString.indexOf(advisor.toString()) != -1);
		assertTrue(proxyConfigString.indexOf("1 interface") != -1);
	}
	
	public void testCanPreventCastToAdvisedUsingOpaque() {
		TestBean target = new TestBean();
		ProxyFactory pc = new ProxyFactory(target);
		pc.setInterfaces(new Class[] { ITestBean.class } );
		pc.addAdvice(new NopInterceptor());
		CountingBeforeAdvice mba = new CountingBeforeAdvice();
		Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut().addMethodName("setAge"), mba);
		pc.addAdvisor(advisor);
		assertFalse("Opaque defaults to false", pc.getOpaque());
		pc.setOpaque(true);
		assertTrue("Opaque now true for this config", pc.getOpaque());
		ITestBean proxied = (ITestBean) createProxy(pc);
		proxied.setAge(10);
		assertEquals(10, proxied.getAge());
		assertEquals(1, mba.getCalls());
		
		assertFalse("Cannot be cast to Advised", proxied instanceof Advised);
	}
	
	public void testAdviceSupportListeners() throws Throwable {
		TestBean target = new TestBean();
		target.setAge(21);
		
		ProxyFactory pc = new ProxyFactory(target);
		CountingAdvisorListener l = new CountingAdvisorListener(pc);
		pc.addListener(l);
		RefreshCountingAdvisorChainFactory acf = new RefreshCountingAdvisorChainFactory();
		// Should be automatically added as a listener
		pc.setAdvisorChainFactory(acf);
		assertFalse(pc.isActive());
		assertEquals(0, l.activates);
		assertEquals(0, acf.refreshes);
		ITestBean proxied = (ITestBean) createProxy(pc);
		assertEquals(1, acf.refreshes);
		assertEquals(1, l.activates);
		assertTrue(pc.isActive());
		assertEquals(target.getAge(), proxied.getAge());
		assertEquals(0, l.adviceChanges);
		NopInterceptor di = new NopInterceptor();
		pc.addAdvice(0, di);
		assertEquals(1, l.adviceChanges);
		assertEquals(2, acf.refreshes);
		assertEquals(target.getAge(), proxied.getAge());
		pc.removeAdvice(di);
		assertEquals(2, l.adviceChanges);
		assertEquals(3, acf.refreshes);
		assertEquals(target.getAge(), proxied.getAge());
		pc.getProxy();
		assertEquals(1, l.activates);
		
		pc.removeListener(l);
		assertEquals(2, l.adviceChanges);
		pc.addAdvisor(new DefaultPointcutAdvisor(new NopInterceptor()));
		// No longer counting
		assertEquals(2, l.adviceChanges);
	}
	
	public void testExistingProxyChangesTarget() throws Throwable {
		TestBean tb1 = new TestBean();
		tb1.setAge(33);
		
		TestBean tb2 = new TestBean();
		tb2.setAge(26);
		tb2.setName("Juergen");
		TestBean tb3 = new TestBean();
		tb3.setAge(37);
		ProxyFactory pc = new ProxyFactory(tb1);
		NopInterceptor nop = new NopInterceptor();
		pc.addAdvice(nop);
		ITestBean proxy = (ITestBean) createProxy(pc);
		assertEquals(nop.getCount(), 0);
		assertEquals(tb1.getAge(), proxy.getAge());
		assertEquals(nop.getCount(), 1);
		// Change to a new static target
		pc.setTarget(tb2);
		assertEquals(tb2.getAge(), proxy.getAge());
		assertEquals(nop.getCount(), 2);
		
		// Change to a new dynamic target
		HotSwappableTargetSource hts = new HotSwappableTargetSource(tb3);
		pc.setTargetSource(hts);
		assertEquals(tb3.getAge(), proxy.getAge());
		assertEquals(nop.getCount(), 3);
		hts.swap(tb1);
		assertEquals(tb1.getAge(), proxy.getAge());
		tb1.setName("Colin");
		assertEquals(tb1.getName(), proxy.getName());
		assertEquals(nop.getCount(), 5);
		
		// Change back, relying on casting to Advised
		Advised advised = (Advised) proxy;
		assertSame(hts, advised.getTargetSource());
		SingletonTargetSource sts = new SingletonTargetSource(tb2);
		advised.setTargetSource(sts);
		assertEquals(tb2.getName(), proxy.getName());
		assertSame(sts, advised.getTargetSource());
		assertEquals(tb2.getAge(), proxy.getAge());
	}
	
	
	public static class CountingAdvisorListener implements AdvisedSupportListener {
		public int adviceChanges;
		public int activates;
		private AdvisedSupport expectedSource;
		
		public CountingAdvisorListener(AdvisedSupport expectedSource) {
			this.expectedSource = expectedSource;
		}
		
		public void adviceChanged(AdvisedSupport as) {
			assertEquals(expectedSource, as);
			++adviceChanges;
		}

		public void activated(AdvisedSupport as) {
			assertEquals(expectedSource, as);
			++activates;
		}
	}
	
	public class RefreshCountingAdvisorChainFactory implements AdvisorChainFactory {
		public int refreshes;
		
		public void adviceChanged(AdvisedSupport pc) {
			++refreshes;
		}

		public List getInterceptorsAndDynamicInterceptionAdvice(Advised pc, Object proxy, Method method, Class targetClass) {
			return AdvisorChainFactoryUtils.calculateInterceptorsAndDynamicInterceptionAdvice(pc, proxy, method, targetClass);
		}
		
		public void activated(AdvisedSupport as) {
			++refreshes;
		}
	}
	
	/**
	 * Fires on setter methods that take a string. Replaces null arg
	 * with ""
	 */
	public static class StringSetterNullReplacementAdvice extends DynamicMethodMatcherPointcutAdvisor {
		
		private static MethodInterceptor cleaner = new MethodInterceptor() {
			public Object invoke(MethodInvocation mi) throws Throwable {
				// We know it can only be invoked if there's a single parameter of type string
				mi.getArguments()[0] = "";
				return mi.proceed();
			}
		};
		
		public StringSetterNullReplacementAdvice() {
			super(cleaner);
		}

		public boolean matches(Method m, Class targetClass, Object[] args){//, AttributeRegistry attributeRegistry) {
			return args[0] == null;
		}

		public boolean matches(Method m, Class targetClass){//, AttributeRegistry attributeRegistry) {
			return m.getName().startsWith("set") &&
				m.getParameterTypes().length == 1 &&
				m.getParameterTypes()[0].equals(String.class);
		}
	}
	
	
	public void testDynamicMethodPointcutThatAlwaysAppliesStatically() throws Throwable {
		TestBean tb = new TestBean();
		ProxyFactory pc = new ProxyFactory(new Class[] { ITestBean.class });
		TestDynamicPointcutAdvice dp = new TestDynamicPointcutAdvice(new NopInterceptor(), "getAge");
		pc.addAdvisor(dp);
		pc.setTarget(tb);
		ITestBean it = (ITestBean) createProxy(pc);
		assertEquals(dp.count, 0);
		int age = it.getAge();
		assertEquals(dp.count, 1);
		it.setAge(11);
		assertEquals(it.getAge(), 11);
		assertEquals(dp.count, 2);
	}
	
	public void testDynamicMethodPointcutThatAppliesStaticallyOnlyToSetters() throws Throwable {
		TestBean tb = new TestBean();
		ProxyFactory pc = new ProxyFactory(new Class[] { ITestBean.class });
		// Could apply dynamically to getAge/setAge but not to getName
		TestDynamicPointcutAdvice dp = new TestDynamicPointcutForSettersOnly(new NopInterceptor(), "Age");
		pc.addAdvisor(dp);
		this.mockTargetSource.setTarget(tb);
		pc.setTargetSource(mockTargetSource);
		ITestBean it = (ITestBean) createProxy(pc);
		assertEquals(dp.count, 0);
		int age = it.getAge();
		// Statically vetoed
		assertEquals(0, dp.count);
		it.setAge(11);
		assertEquals(it.getAge(), 11);
		assertEquals(dp.count, 1);
		// Applies statically but not dynamically
		it.setName("joe");
		assertEquals(dp.count, 1);
	}
	
	
	public void testStaticMethodPointcut() throws Throwable {
		TestBean tb = new TestBean();
		ProxyFactory pc = new ProxyFactory(new Class[] { ITestBean.class });
		NopInterceptor di = new NopInterceptor();
		TestStaticPointcutAdvice sp = new TestStaticPointcutAdvice(di, "getAge");
		pc.addAdvisor(sp);
		pc.setTarget(tb);
		ITestBean it = (ITestBean) createProxy(pc);
		assertEquals(di.getCount(), 0);
		int age = it.getAge();
		assertEquals(di.getCount(), 1);
		it.setAge(11);
		assertEquals(it.getAge(), 11);
		assertEquals(di.getCount(), 2);
	}
	
	/**
	 * There are times when we want to call proceed()
	 * twice. We can do this if we clone the invocation.
	 * @throws Throwable
	 */
	public void testCloneInvocationToProceedThreeTimes() throws Throwable {
		TestBean tb = new TestBean();
		ProxyFactory pc = new ProxyFactory(tb);
		pc.addInterface(ITestBean.class);
		
		MethodInterceptor twoBirthdayInterceptor = new MethodInterceptor() {
			public Object invoke(MethodInvocation mi) throws Throwable {
				// Clone the invocation to proceed three times
				// "The Moor's Last Sigh": this technology can cause premature aging
				MethodInvocation clone1 = ((ReflectiveMethodInvocation) mi).invocableClone();
				MethodInvocation clone2 = ((ReflectiveMethodInvocation) mi).invocableClone();
				clone1.proceed();
				clone2.proceed();
				return mi.proceed();
			}
		};
		StaticMethodMatcherPointcutAdvisor advisor = new StaticMethodMatcherPointcutAdvisor(twoBirthdayInterceptor) {
			public boolean matches(Method m, Class targetClass) {
				return "haveBirthday".equals(m.getName());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -