📄 abstractaopproxytests.java
字号:
}
}
/**
* 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 + -