📄 abstractaopproxytests.java
字号:
assertEquals("Only one invocation via AOP as use of this wasn't proxied", 1, di.getCount());
// 1 invocation
assertEquals("Increment happened", 1, proxied.getCount());
proxied.incrementViaProxy(); // 2 invoocations
assertEquals("Increment happened", 2, target.getCount());
assertEquals("3 more invocations via AOP as the first call was reentrant through the proxy", 4, di.getCount());
}
public void testTargetCantGetProxyByDefault() {
NeedsToSeeProxy et = new NeedsToSeeProxy();
ProxyFactory pf1 = new ProxyFactory(et);
assertFalse(pf1.getExposeProxy());
INeedsToSeeProxy proxied = (INeedsToSeeProxy) createProxy(pf1);
try {
proxied.incrementViaProxy();
fail("Should have failed to get proxy as exposeProxy wasn't set to true");
}
catch (AspectException ex) {
// Ok
}
}
public void testContext() throws Throwable {
testContext(true);
}
public void testNoContext() throws Throwable {
testContext(false);
}
/**
* @param context if true, want context
* @throws Throwable
*/
private void testContext(final boolean context) throws Throwable {
final String s = "foo";
// Test return value
MethodInterceptor mi = new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
if (!context) {
assertNoInvocationContext();
} else {
assertTrue("have context", ExposeInvocationInterceptor.currentInvocation() != null);
}
return s;
}
};
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class });
if (context) {
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
}
pc.addAdvice(mi);
// Keep CGLIB happy
if (requiresTarget()) {
pc.setTarget(new TestBean());
}
AopProxy aop = createAopProxy(pc);
assertNoInvocationContext();
ITestBean tb = (ITestBean) aop.getProxy();
assertNoInvocationContext();
assertTrue("correct return value", tb.getName() == s);
}
public static class OwnSpouse extends TestBean {
public ITestBean getSpouse() {
return this;
}
}
/**
* Test that the proxy returns itself when the
* target returns <code>this</code>
* @throws Throwable
*/
public void testTargetReturnsThis() throws Throwable {
// Test return value
TestBean raw = new OwnSpouse();
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class });
pc.setTarget(raw);
ITestBean tb = (ITestBean) createProxy(pc);
assertTrue("this return is wrapped in proxy", tb.getSpouse() == tb);
}
/*
public void testCanAttach() throws Throwable {
final TrapInterceptor tii = new TrapInvocationInterceptor();
ProxyConfig pc = new ProxyConfigSupport(new Class[] { ITestBean.class }, false);
pc.addAdvice(tii);
pc.addAdvice(new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
assertTrue("Saw same interceptor", invocation == tii.invocation);
return null;
}
});
AopProxy aop = new AopProxy(pc, new MethodInvocationFactorySupport());
ITestBean tb = (ITestBean) aop.getProxy();
tb.getSpouse();
assertTrue(tii.invocation != null);
// TODO strengthen this
// assertTrue(tii.invocation.getProxy() == tb);
assertTrue(tii.invocation.getThis() == null);
}
*/
public void testDeclaredException() throws Throwable {
final Exception expectedException = new Exception();
// Test return value
MethodInterceptor mi = new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
throw expectedException;
}
};
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class });
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
pc.addAdvice(mi);
// We don't care about the object
mockTargetSource.setTarget(new Object());
pc.setTargetSource(mockTargetSource);
AopProxy aop = createAopProxy(pc);
try {
ITestBean tb = (ITestBean) aop.getProxy();
// Note: exception param below isn't used
tb.exceptional(expectedException);
fail("Should have thrown exception raised by interceptor");
}
catch (Exception thrown) {
assertEquals("exception matches", expectedException, thrown);
}
}
/**
* An interceptor throws a checked exception not on the method signature.
* For efficiency, we don't bother unifying java.lang.reflect and
* net.sf.cglib UndeclaredThrowableException
* @throws Throwable
*/
public void testUndeclaredCheckedException() throws Throwable {
final Exception unexpectedException = new Exception();
// Test return value
MethodInterceptor mi = new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
throw unexpectedException;
}
};
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class });
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
pc.addAdvice(mi);
// We don't care about the object
pc.setTarget(new TestBean());
AopProxy aop = createAopProxy(pc);
ITestBean tb = (ITestBean) aop.getProxy();
try {
// Note: exception param below isn't used
tb.getAge();
fail("Should have wrapped exception raised by interceptor");
}
catch (UndeclaredThrowableException thrown) {
assertEquals("exception matches", unexpectedException, thrown.getUndeclaredThrowable());
}
//catch (net.sf.cglib.proxy.UndeclaredThrowableException thrown) {
// assertEquals("exception matches", unexpectedException, thrown.getUndeclaredThrowable());
//}
catch (Exception ex) {
ex.printStackTrace();
fail("Didn't expect exception: " + ex);
}
}
public void testUndeclaredUnheckedException() throws Throwable {
final RuntimeException unexpectedException = new RuntimeException();
// Test return value
MethodInterceptor mi = new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
throw unexpectedException;
}
};
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class });
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
pc.addAdvice(mi);
// We don't care about the object
pc.setTarget(new TestBean());
AopProxy aop = createAopProxy(pc);
ITestBean tb = (ITestBean) aop.getProxy();
try {
// Note: exception param below isn't used
tb.getAge();
fail("Should have wrapped exception raised by interceptor");
}
catch (RuntimeException thrown) {
assertEquals("exception matches", unexpectedException, thrown);
}
//catch (net.sf.cglib.proxy.UndeclaredThrowableException thrown) {
// assertEquals("exception matches", unexpectedException, thrown.getUndeclaredThrowable());
//}
}
/**
* Check that although a method is eligible for advice chain optimization and
* direct reflective invocation, it doesn't happen if we've asked to see the proxy,
* so as to guarantee a consistent programming model.
* @throws Throwable
*/
public void testTargetCanGetInvocationEvenIfNoAdviceChain() throws Throwable {
NeedsToSeeProxy target = new NeedsToSeeProxy();
AdvisedSupport pc = new AdvisedSupport(new Class[] { INeedsToSeeProxy.class } );
pc.setTarget(target);
pc.setExposeProxy(true);
// Now let's try it with the special target
AopProxy aop = createAopProxy(pc);
INeedsToSeeProxy proxied = (INeedsToSeeProxy) aop.getProxy();
// It will complain if it can't get the proxy
proxied.incrementViaProxy();
}
public void testTargetCanGetInvocation() throws Throwable {
final InvocationCheckExposedInvocationTestBean expectedTarget = new InvocationCheckExposedInvocationTestBean();
AdvisedSupport pc = new AdvisedSupport(new Class[] { ITestBean.class, IOther.class });
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
TrapTargetInterceptor tii = new TrapTargetInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
// Assert that target matches BEFORE invocation returns
assertEquals("Target is correct", expectedTarget, invocation.getThis());
return super.invoke(invocation);
}
};
pc.addAdvice(tii);
pc.setTarget(expectedTarget);
AopProxy aop = createAopProxy(pc);
ITestBean tb = (ITestBean) aop.getProxy();
tb.getName();
// Not safe to trap invocation
//assertTrue(tii.invocation == target.invocation);
//assertTrue(target.invocation.getProxy() == tb);
// ((IOther) tb).absquatulate();
//MethodInvocation minv = tii.invocation;
//assertTrue("invoked on iother, not " + minv.getMethod().getDeclaringClass(), minv.getMethod().getDeclaringClass() == IOther.class);
//assertTrue(target.invocation == tii.invocation);
}
/**
* Throw an exception if there is an Invocation
*/
private void assertNoInvocationContext() {
try {
ExposeInvocationInterceptor.currentInvocation();
fail("Expected no invocation context");
} catch (AspectException ex) {
// ok
}
}
/**
* Test stateful interceptor
* @throws Throwable
*/
public void testMixin() throws Throwable {
TestBean tb = new TestBean();
ProxyFactory pc = new ProxyFactory(new Class[] { Lockable.class, ITestBean.class });
pc.addAdvisor(new LockMixinAdvisor());
pc.setTarget(tb);
int newAge = 65;
ITestBean itb = (ITestBean) createProxy(pc);
itb.setAge(newAge);
assertTrue(itb.getAge() == newAge);
Lockable lockable = (Lockable) itb;
assertFalse(lockable.locked());
lockable.lock();
assertTrue(itb.getAge() == newAge);
try {
itb.setAge(1);
fail("Setters should fail when locked");
}
catch (LockedException ex) {
// ok
}
assertTrue(itb.getAge() == newAge);
// Unlock
assertTrue(lockable.locked());
lockable.unlock();
itb.setAge(1);
assertTrue(itb.getAge() == 1);
}
public void testReplaceArgument() throws Throwable {
TestBean tb = new TestBean();
ProxyFactory pc = new ProxyFactory(new Class[] { ITestBean.class });
pc.setTarget(tb);
pc.addAdvisor(new StringSetterNullReplacementAdvice());
ITestBean t = (ITestBean) pc.getProxy();
int newAge = 5;
t.setAge(newAge);
assertTrue(t.getAge() == newAge);
String newName = "greg";
t.setName(newName);
assertEquals(newName, t.getName());
t.setName(null);
// Null replacement magic should work
assertTrue(t.getName().equals(""));
}
public void testCanCastProxyToProxyConfig() throws Throwable {
TestBean tb = new TestBean();
ProxyFactory pc = new ProxyFactory(tb);
NopInterceptor di = new NopInterceptor();
pc.addAdvice(0, di);
ITestBean t = (ITestBean) createProxy(pc);
assertEquals(0, di.getCount());
t.setAge(23);
assertEquals(23, t.getAge());
assertEquals(2, di.getCount());
Advised advised = (Advised) t;
assertEquals("Have 1 advisor", 1, advised.getAdvisors().length);
assertEquals(di, advised.getAdvisors()[0].getAdvice());
NopInterceptor di2 = new NopInterceptor();
advised.addAdvice(1, di2);
t.getName();
assertEquals(3, di.getCount());
assertEquals(1, di2.getCount());
// will remove di
advised.removeAdvisor(0);
t.getAge();
// Unchanged
assertEquals(3, di.getCount());
assertEquals(2, di2.getCount());
CountingBeforeAdvice cba = new CountingBeforeAdvice();
assertEquals(0, cba.getCalls());
advised.addAdvice(cba);
t.setAge(16);
assertEquals(16, t.getAge());
assertEquals(2, cba.getCalls());
}
public void testAdviceImplementsIntroductionInfo() throws Throwable {
TestBean tb = new TestBean();
String name = "tony";
tb.setName(name);
ProxyFactory pc = new ProxyFactory(tb);
NopInterceptor di = new NopInterceptor();
pc.addAdvice(di);
final long ts = 37;
pc.addAdvice(new DelegatingIntroductionInterceptor(new TimeStamped() {
/**
* @see org.springframework.aop.framework.TimeStamped#getTimeStamp()
*/
public long getTimeStamp() {
return ts;
}
}));
ITestBean proxied = (ITestBean) createProxy(pc);
assertEquals(name, proxied.getName());
TimeStamped intro = (TimeStamped) proxied;
assertEquals(ts, intro.getTimeStamp());
}
public void testCannotAddDynamicIntroductionAdviceExceptInIntroductionAdvice() throws Throwable {
TestBean target = new TestBean();
target.setAge(21);
ProxyFactory pc = new ProxyFactory(target);
try {
pc.addAdvice(new DummyIntroductionAdviceImpl());
fail("Shouldn't be able to add introduction interceptor except via introduction advice");
}
catch (AopConfigException 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());
}
public void testRejectsBogusDynamicIntroductionAdviceWithNoAdapter() throws Throwable {
TestBean target = new TestBean();
target.setAge(21);
ProxyFactory pc = new ProxyFactory(target);
pc.addAdvisor(new DefaultIntroductionAdvisor(new DummyIntroductionAdviceImpl(), Comparable.class));
try {
// TODO May fail on either call: may want to tighten up definition
ITestBean proxied = (ITestBean) createProxy(pc);
proxied.getName();
fail("Bogus introduction");
}
catch (Exception ex) {
// TODO used to catch UnknownAdviceTypeException, but
// with CGLIB some errors are in proxy creation and are wrapped
// in aspect exception. Error message is still fine.
//assertTrue(ex.getMessage().indexOf("ntroduction") > -1);
}
}
private class DummyIntroductionAdviceImpl implements DynamicIntroductionAdvice {
/**
* @see org.springframework.aop.DynamicIntroductionAdvice#implementsInterface(java.lang.Class)
*/
public boolean implementsInterface(Class intf) {
return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -