📄 abstractaopproxytests.java
字号:
TestBean target = new TestBean();
target.setAge(80);
NopInterceptor nop1 = new NopInterceptor();
NopInterceptor nop2 = new NopInterceptor();
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(nop1);
pf.addAdvice(ba);
pf.addAdvice(nop2);
ITestBean proxied = (ITestBean) createProxy(pf);
// Won't throw an exception
assertEquals(target.getAge(), proxied.getAge());
assertEquals(1, ba.getCalls());
assertEquals(1, ba.getCalls("getAge"));
assertEquals(1, nop1.getCount());
assertEquals(1, nop2.getCount());
// Will fail, after invoking Nop1
try {
proxied.setAge(26);
fail("before advice should have ended chain");
}
catch (RuntimeException ex) {
assertEquals(rex, ex);
}
assertEquals(2, ba.getCalls());
assertEquals(2, nop1.getCount());
// Nop2 didn't get invoked when the exception was thrown
assertEquals(1, nop2.getCount());
// Shouldn't have changed value in joinpoint
assertEquals(target.getAge(), proxied.getAge());
}
public void testAfterReturningAdvisorIsInvoked() {
class SummingAfterAdvice implements AfterReturningAdvice {
public int sum;
public void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable {
sum += ((Integer) returnValue).intValue();
}
}
SummingAfterAdvice aa = new SummingAfterAdvice();
Advisor matchesInt = new StaticMethodMatcherPointcutAdvisor(aa) {
public boolean matches(Method m, Class targetClass) {
return m.getReturnType() == int.class;
}
};
TestBean target = new TestBean();
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(new NopInterceptor());
pf.addAdvisor(matchesInt);
assertEquals("Advisor was added", matchesInt, pf.getAdvisors()[1]);
ITestBean proxied = (ITestBean) createProxy(pf);
assertEquals(0, aa.sum);
int i1 = 12;
int i2 = 13;
// Won't be advised
proxied.setAge(i1);
assertEquals(i1, proxied.getAge());
assertEquals(i1, aa.sum);
proxied.setAge(i2);
assertEquals(i2, proxied.getAge());
assertEquals(i1 + i2, aa.sum);
assertEquals(i2, proxied.getAge());
}
public void testAfterReturningAdvisorIsNotInvokedOnException() {
CountingAfterReturningAdvice car = new CountingAfterReturningAdvice();
TestBean target = new TestBean();
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(new NopInterceptor());
pf.addAdvice(car);
assertEquals("Advice was wrapped in Advisor and added", car, pf.getAdvisors()[1].getAdvice());
ITestBean proxied = (ITestBean) createProxy(pf);
assertEquals(0, car.getCalls());
int age = 10;
proxied.setAge(age);
assertEquals(age, proxied.getAge());
assertEquals(2, car.getCalls());
Exception exc = new Exception();
// On exception it won't be invoked
try {
proxied.exceptional(exc);
fail();
}
catch (Throwable t) {
assertSame(exc, t);
}
assertEquals(2, car.getCalls());
}
public void testThrowsAdvisorIsInvoked() throws Throwable {
// Reacts to ServletException and RemoteException
ThrowsAdviceInterceptorTests.MyThrowsHandler th = new ThrowsAdviceInterceptorTests.MyThrowsHandler();
Advisor matchesEchoInvocations = new StaticMethodMatcherPointcutAdvisor(th) {
public boolean matches(Method m, Class targetClass) {
return m.getName().startsWith("echo");
}
};
ThrowsAdviceInterceptorTests.Echo target = new ThrowsAdviceInterceptorTests.Echo();
target.setA(16);
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(new NopInterceptor());
pf.addAdvisor(matchesEchoInvocations);
assertEquals("Advisor was added", matchesEchoInvocations, pf.getAdvisors()[1]);
ThrowsAdviceInterceptorTests.IEcho proxied = (ThrowsAdviceInterceptorTests.IEcho) createProxy(pf);
assertEquals(0, th.getCalls());
assertEquals(target.getA(), proxied.getA());
assertEquals(0, th.getCalls());
Exception ex = new Exception();
// Will be advised but doesn't match
try {
proxied.echoException(1, ex);
fail();
}
catch (Exception caught) {
assertEquals(ex, caught);
}
ex = new ServletException();
try {
proxied.echoException(1, ex);
fail();
}
catch (ServletException caught) {
assertEquals(ex, caught);
}
assertEquals(1, th.getCalls("servletException"));
}
public void testAddThrowsAdviceWithoutAdvisor() throws Throwable {
// Reacts to ServletException and RemoteException
ThrowsAdviceInterceptorTests.MyThrowsHandler th = new ThrowsAdviceInterceptorTests.MyThrowsHandler();
ThrowsAdviceInterceptorTests.Echo target = new ThrowsAdviceInterceptorTests.Echo();
target.setA(16);
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(new NopInterceptor());
pf.addAdvice(th);
ThrowsAdviceInterceptorTests.IEcho proxied = (ThrowsAdviceInterceptorTests.IEcho) createProxy(pf);
assertEquals(0, th.getCalls());
assertEquals(target.getA(), proxied.getA());
assertEquals(0, th.getCalls());
Exception ex = new Exception();
// Will be advised but doesn't match
try {
proxied.echoException(1, ex);
fail();
}
catch (Exception caught) {
assertEquals(ex, caught);
}
// Subclass of RemoteException
ex = new TransactionRequiredException();
try {
proxied.echoException(1, ex);
fail();
}
catch (TransactionRequiredException caught) {
assertEquals(ex, caught);
}
assertEquals(1, th.getCalls("remoteException"));
}
private static class CheckMethodInvocationIsSameInAndOutInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
Method m = mi.getMethod();
Object retval = mi.proceed();
assertEquals("Method invocation has same method on way back", m, mi.getMethod());
return retval;
}
}
/**
* ExposeInvocation must be set to true.
*/
private static class CheckMethodInvocationViaThreadLocalIsSameInAndOutInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
String task = "get invocation on way IN";
try {
MethodInvocation current = ExposeInvocationInterceptor.currentInvocation();
assertEquals(mi, current);
Object retval = mi.proceed();
task = "get invocation on way OUT";
assertEquals(current, ExposeInvocationInterceptor.currentInvocation());
return retval;
}
catch (AspectException ex) {
System.err.println(task + " for " + mi.getMethod());
ex.printStackTrace();
//fail("Can't find invocation: " + ex);
throw ex;
}
}
}
/**
* Same thing for a proxy.
* Only works when exposeProxy is set to true.
* Checks that the proxy is the same on the way in and out.
*/
private static class ProxyMatcherInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
Object proxy = AopContext.currentProxy();
Object ret = mi.proceed();
// TODO why does this cause stack overflow?
//assertEquals(proxy, AopContext.currentProxy());
assertTrue(proxy == AopContext.currentProxy());
return ret;
}
}
protected static class TestDynamicPointcutAdvice extends DynamicMethodMatcherPointcutAdvisor {
private String pattern;
public int count;
public TestDynamicPointcutAdvice(MethodInterceptor mi, String pattern) {
super(mi);
this.pattern = pattern;
}
public boolean matches(Method m, Class targetClass, Object[] args) {
boolean run = m.getName().indexOf(pattern) != -1;
if (run) ++count;
return run;
}
}
protected static class TestDynamicPointcutForSettersOnly extends TestDynamicPointcutAdvice {
public TestDynamicPointcutForSettersOnly(MethodInterceptor mi, String pattern) {
super(mi, pattern);
}
public boolean matches(Method m, Class clazz) {
return m.getName().startsWith("set");
}
}
protected static class TestStaticPointcutAdvice extends StaticMethodMatcherPointcutAdvisor {
private String pattern;
private int count;
public TestStaticPointcutAdvice(MethodInterceptor mi, String pattern) {
super(mi);
this.pattern = pattern;
}
public boolean matches(Method m, Class targetClass) {
boolean run = m.getName().indexOf(pattern) != -1;
if (run) ++count;
return run;
}
}
/**
* Note that trapping the Invocation as in previous version of this test
* isn't safe, as invocations may be reused
* and hence cleared at the end of each invocation.
* So we trap only the targe.
*/
protected static class TrapTargetInterceptor implements MethodInterceptor {
public Object target;
public Object invoke(MethodInvocation invocation) throws Throwable {
this.target = invocation.getThis();
return invocation.proceed();
}
}
private static class DummyIntroductionAdviceImpl implements DynamicIntroductionAdvice {
public boolean implementsInterface(Class intf) {
return true;
}
}
public static class OwnSpouse extends TestBean {
public ITestBean getSpouse() {
return this;
}
}
private static class EqualsTestBean extends TestBean {
public ITestBean getSpouse() {
return this;
}
}
public static class AllInstancesAreEqual implements IOther {
public boolean equals(Object o) {
return o instanceof AllInstancesAreEqual;
}
public void absquatulate() {
}
}
public interface INeedsToSeeProxy {
int getCount();
void incrementViaThis();
void incrementViaProxy();
void increment();
}
public static class NeedsToSeeProxy implements INeedsToSeeProxy {
private int count;
public int getCount() {
return count;
}
public void incrementViaThis() {
this.increment();
}
public void incrementViaProxy() {
INeedsToSeeProxy thisViaProxy = (INeedsToSeeProxy) AopContext.currentProxy();
thisViaProxy.increment();
Advised advised = (Advised) thisViaProxy;
checkAdvised(advised);
}
protected void checkAdvised(Advised advised) {
}
public void increment() {
++count;
}
}
public static class TargetChecker extends NeedsToSeeProxy {
protected void checkAdvised(Advised advised) {
// TODO replace this check: no longer possible
//assertEquals(advised.getTarget(), this);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -