moving .aop.aspectj.* unit tests from .testsuite -> .context

This commit is contained in:
Chris Beams
2008-12-19 03:45:30 +00:00
parent b6906ecfb7
commit 5b9da399c6
53 changed files with 77 additions and 4 deletions

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.AdviceBindingTestAspect.AdviceBindingCollaborator;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for various parameter binding scenarios with before advice.
*
* @author Adrian Colyer
* @author Rod Johnson
* @author Chris Beams
*/
public final class AfterAdviceBindingTests {
private AdviceBindingCollaborator mockCollaborator;
private ITestBean testBeanProxy;
private TestBean testBeanTarget;
@Before
public void setUp() throws Exception {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
AdviceBindingTestAspect afterAdviceAspect = (AdviceBindingTestAspect) ctx.getBean("testAspect");
testBeanProxy = (ITestBean) ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(testBeanProxy));
// we need the real target too, not just the proxy...
testBeanTarget = (TestBean) ((Advised) testBeanProxy).getTargetSource().getTarget();
mockCollaborator = createNiceMock(AdviceBindingCollaborator.class);
afterAdviceAspect.setCollaborator(mockCollaborator);
}
@Test
public void testOneIntArg() {
mockCollaborator.oneIntArg(5);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testOneObjectArgBindingProxyWithThis() {
mockCollaborator.oneObjectArg(this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testOneObjectArgBindingTarget() {
mockCollaborator.oneObjectArg(this.testBeanTarget);
replay(mockCollaborator);
testBeanProxy.getDoctor();
verify(mockCollaborator);
}
@Test
public void testOneIntAndOneObjectArgs() {
mockCollaborator.oneIntAndOneObject(5,this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPoint() {
mockCollaborator.needsJoinPoint("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPointStaticPart() {
mockCollaborator.needsJoinPointStaticPart("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="afterAdviceBindingTests" ref="testAspect">
<aop:after method="oneIntArg" pointcut="execution(* setAge(int)) and args(age)"/>
<aop:after method="oneObjectArg" pointcut="execution(* getAge()) and this(bean)"/>
<aop:after method="oneObjectArg" pointcut="execution(* getDoctor()) and target(bean)"/>
<aop:after method="oneIntAndOneObject"
pointcut="execution(* setAge(..)) and args(age) and this(bean)" arg-names="age,bean"/>
<aop:after method="needsJoinPoint" pointcut="execution(* getAge())"/>
<aop:after method="needsJoinPointStaticPart" pointcut="execution(* getAge())"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,219 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.AfterReturningAdviceBindingTestAspect.AfterReturningAdviceBindingCollaborator;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for various parameter binding scenarios with before advice.
*
* @author Adrian Colyer
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class AfterReturningAdviceBindingTests {
private AfterReturningAdviceBindingTestAspect afterAdviceAspect;
private ITestBean testBeanProxy;
private TestBean testBeanTarget;
private AfterReturningAdviceBindingCollaborator mockCollaborator;
public void setAfterReturningAdviceAspect(AfterReturningAdviceBindingTestAspect anAspect) {
this.afterAdviceAspect = anAspect;
}
@Before
public void setUp() throws Exception {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
afterAdviceAspect = (AfterReturningAdviceBindingTestAspect) ctx.getBean("testAspect");
mockCollaborator = createNiceMock(AfterReturningAdviceBindingCollaborator.class);
afterAdviceAspect.setCollaborator(mockCollaborator);
testBeanProxy = (ITestBean) ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(testBeanProxy));
// we need the real target too, not just the proxy...
this.testBeanTarget = (TestBean) ((Advised)testBeanProxy).getTargetSource().getTarget();
}
@Test
public void testOneIntArg() {
mockCollaborator.oneIntArg(5);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testOneObjectArg() {
mockCollaborator.oneObjectArg(this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testOneIntAndOneObjectArgs() {
mockCollaborator.oneIntAndOneObject(5,this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPoint() {
mockCollaborator.needsJoinPoint("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPointStaticPart() {
mockCollaborator.needsJoinPointStaticPart("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testReturningString() {
mockCollaborator.oneString("adrian");
replay(mockCollaborator);
testBeanProxy.setName("adrian");
testBeanProxy.getName();
verify(mockCollaborator);
}
@Test
public void testReturningObject() {
mockCollaborator.oneObjectArg(this.testBeanTarget);
replay(mockCollaborator);
testBeanProxy.returnsThis();
verify(mockCollaborator);
}
@Test
public void testReturningBean() {
mockCollaborator.oneTestBeanArg(this.testBeanTarget);
replay(mockCollaborator);
testBeanProxy.returnsThis();
verify(mockCollaborator);
}
@Test
public void testReturningBeanArray() {
this.testBeanTarget.setSpouse(new TestBean());
ITestBean[] spouses = (ITestBean[]) this.testBeanTarget.getSpouses();
mockCollaborator.testBeanArrayArg(spouses);
replay(mockCollaborator);
testBeanProxy.getSpouses();
verify(mockCollaborator);
}
@Test
public void testNoInvokeWhenReturningParameterTypeDoesNotMatch() {
// we need a strict mock for this...
mockCollaborator = createMock(AfterReturningAdviceBindingCollaborator.class);
afterAdviceAspect.setCollaborator(mockCollaborator);
replay(mockCollaborator);
testBeanProxy.setSpouse(this.testBeanProxy);
testBeanProxy.getSpouse();
verify(mockCollaborator);
}
@Test
public void testReturningByType() {
mockCollaborator.objectMatchNoArgs();
replay(mockCollaborator);
testBeanProxy.returnsThis();
verify(mockCollaborator);
}
@Test
public void testReturningPrimitive() {
mockCollaborator.oneInt(20);
replay(mockCollaborator);
testBeanProxy.setAge(20);
testBeanProxy.haveBirthday();
verify(mockCollaborator);
}
}
final class AfterReturningAdviceBindingTestAspect extends AdviceBindingTestAspect {
private AfterReturningAdviceBindingCollaborator getCollaborator() {
return (AfterReturningAdviceBindingCollaborator) this.collaborator;
}
public void oneString(String name) {
getCollaborator().oneString(name);
}
public void oneTestBeanArg(TestBean bean) {
getCollaborator().oneTestBeanArg(bean);
}
public void testBeanArrayArg(ITestBean[] beans) {
getCollaborator().testBeanArrayArg(beans);
}
public void objectMatchNoArgs() {
getCollaborator().objectMatchNoArgs();
}
public void stringMatchNoArgs() {
getCollaborator().stringMatchNoArgs();
}
public void oneInt(int result) {
getCollaborator().oneInt(result);
}
interface AfterReturningAdviceBindingCollaborator extends AdviceBindingCollaborator {
void oneString(String s);
void oneTestBeanArg(TestBean b);
void testBeanArrayArg(ITestBean[] b);
void objectMatchNoArgs();
void stringMatchNoArgs();
void oneInt(int result);
}
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="afterReturningAdviceBindingTests" ref="testAspect">
<aop:after-returning method="oneIntArg" pointcut="execution(* setAge(int)) and args(age)"/>
<aop:after-returning method="oneObjectArg" pointcut="execution(* getAge()) and this(bean)"/>
<aop:after-returning method="oneIntAndOneObject"
pointcut="execution(* setAge(..)) and args(age) and this(bean)" arg-names="age,bean"/>
<aop:after-returning method="needsJoinPoint" pointcut="execution(* getAge())"/>
<aop:after-returning method="needsJoinPointStaticPart" pointcut="execution(* getAge())"/>
<!-- additional tests using the returning attribute -->
<aop:after-returning method="oneString" returning="name" pointcut="execution(* getName())"/>
<aop:after-returning method="oneObjectArg" returning="bean" pointcut="execution(* returnsThis())"/>
<aop:after-returning method="oneTestBeanArg" returning="bean" pointcut="execution(* returnsThis())"/>
<aop:after-returning method="testBeanArrayArg" returning="beans"
pointcut="execution(org.springframework.beans.ITestBean[] *(..))"/>
<aop:after-returning method="oneString" returning="name" pointcut="execution(* getSpouse())"/>
<aop:after-returning method="objectMatchNoArgs" returning="java.lang.Object"
pointcut="execution(* returnsThis())"/>
<aop:after-returning method="stringMatchNoArgs" returning="java.lang.String"
pointcut="execution(* getSpouse())"/>
<aop:after-returning method="oneInt" returning="result" pointcut="execution(* haveBirthday())"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AfterReturningAdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.easymock.EasyMock.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.AfterThrowingAdviceBindingTestAspect.AfterThrowingAdviceBindingCollaborator;
import org.springframework.beans.ITestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for various parameter binding scenarios with before advice.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public final class AfterThrowingAdviceBindingTests {
private ITestBean testBean;
private AfterThrowingAdviceBindingTestAspect afterThrowingAdviceAspect;
private AfterThrowingAdviceBindingCollaborator mockCollaborator;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean = (ITestBean) ctx.getBean("testBean");
afterThrowingAdviceAspect = (AfterThrowingAdviceBindingTestAspect) ctx.getBean("testAspect");
mockCollaborator = createNiceMock(AfterThrowingAdviceBindingCollaborator.class);
afterThrowingAdviceAspect.setCollaborator(mockCollaborator);
}
@After
public void tearDown() {
verify(mockCollaborator);
}
@Test(expected=Throwable.class)
public void testSimpleAfterThrowing() throws Throwable {
mockCollaborator.noArgs();
replay(mockCollaborator);
this.testBean.exceptional(new Throwable());
}
@Test(expected=Throwable.class)
public void testAfterThrowingWithBinding() throws Throwable {
Throwable t = new Throwable();
mockCollaborator.oneThrowable(t);
replay(mockCollaborator);
this.testBean.exceptional(t);
}
@Test(expected=Throwable.class)
public void testAfterThrowingWithNamedTypeRestriction() throws Throwable {
Throwable t = new Throwable();
// need a strict mock for this test...
mockCollaborator = createMock(AfterThrowingAdviceBindingCollaborator.class);
afterThrowingAdviceAspect.setCollaborator(mockCollaborator);
mockCollaborator.noArgs();
mockCollaborator.oneThrowable(t);
mockCollaborator.noArgsOnThrowableMatch();
replay(mockCollaborator);
this.testBean.exceptional(t);
}
@Test(expected=Throwable.class)
public void testAfterThrowingWithRuntimeExceptionBinding() throws Throwable {
RuntimeException ex = new RuntimeException();
mockCollaborator.oneRuntimeException(ex);
replay(mockCollaborator);
this.testBean.exceptional(ex);
}
@Test(expected=Throwable.class)
public void testAfterThrowingWithTypeSpecified() throws Throwable {
mockCollaborator.noArgsOnThrowableMatch();
replay(mockCollaborator);
this.testBean.exceptional(new Throwable());
}
@Test(expected=Throwable.class)
public void testAfterThrowingWithRuntimeTypeSpecified() throws Throwable {
mockCollaborator.noArgsOnRuntimeExceptionMatch();
replay(mockCollaborator);
this.testBean.exceptional(new RuntimeException());
verify(mockCollaborator);
}
}
final class AfterThrowingAdviceBindingTestAspect {
// collaborator interface that makes it easy to test this aspect is
// working as expected through mocking.
public interface AfterThrowingAdviceBindingCollaborator {
void noArgs();
void oneThrowable(Throwable t);
void oneRuntimeException(RuntimeException re);
void noArgsOnThrowableMatch();
void noArgsOnRuntimeExceptionMatch();
}
protected AfterThrowingAdviceBindingCollaborator collaborator = null;
public void setCollaborator(AfterThrowingAdviceBindingCollaborator aCollaborator) {
this.collaborator = aCollaborator;
}
public void noArgs() {
this.collaborator.noArgs();
}
public void oneThrowable(Throwable t) {
this.collaborator.oneThrowable(t);
}
public void oneRuntimeException(RuntimeException ex) {
this.collaborator.oneRuntimeException(ex);
}
public void noArgsOnThrowableMatch() {
this.collaborator.noArgsOnThrowableMatch();
}
public void noArgsOnRuntimeExceptionMatch() {
this.collaborator.noArgsOnRuntimeExceptionMatch();
}
}

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="afterThrowingAdviceBindingTests" ref="testAspect">
<aop:after-throwing
method="noArgs"
pointcut="execution(* exceptional(..))"
/>
<aop:after-throwing
method="oneThrowable"
throwing="t"
pointcut="execution(* exceptional(..))"
/>
<aop:after-throwing
method="oneRuntimeException"
throwing="ex"
pointcut="execution(* exceptional(..))"
/>
<aop:after-throwing
method="noArgsOnThrowableMatch"
throwing="java.lang.Throwable"
pointcut="execution(* exceptional(..))"
/>
<aop:after-throwing
method="noArgsOnRuntimeExceptionMatch"
throwing="java.lang.RuntimeException"
pointcut="execution(* exceptional(..))"
/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AfterThrowingAdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertTrue;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.AroundAdviceBindingTestAspect.AroundAdviceBindingCollaborator;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for various parameter binding scenarios with before advice.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public class AroundAdviceBindingTests {
private AroundAdviceBindingCollaborator mockCollaborator;
private ITestBean testBeanProxy;
private TestBean testBeanTarget;
protected ApplicationContext ctx;
@Before
public void onSetUp() throws Exception {
ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
AroundAdviceBindingTestAspect aroundAdviceAspect = ((AroundAdviceBindingTestAspect) ctx.getBean("testAspect"));
ITestBean injectedTestBean = (ITestBean) ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(injectedTestBean));
this.testBeanProxy = injectedTestBean;
// we need the real target too, not just the proxy...
this.testBeanTarget = (TestBean) ((Advised) testBeanProxy).getTargetSource().getTarget();
mockCollaborator = createNiceMock(AroundAdviceBindingCollaborator.class);
aroundAdviceAspect.setCollaborator(mockCollaborator);
}
@Test
public void testOneIntArg() {
mockCollaborator.oneIntArg(5);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testOneObjectArgBoundToTarget() {
mockCollaborator.oneObjectArg(this.testBeanTarget);
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testOneIntAndOneObjectArgs() {
mockCollaborator.oneIntAndOneObject(5, this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testJustJoinPoint() {
mockCollaborator.justJoinPoint("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
}
class AroundAdviceBindingTestAspect {
private AroundAdviceBindingCollaborator collaborator = null;
public void setCollaborator(AroundAdviceBindingCollaborator aCollaborator) {
this.collaborator = aCollaborator;
}
// "advice" methods
public void oneIntArg(ProceedingJoinPoint pjp, int age) throws Throwable {
this.collaborator.oneIntArg(age);
pjp.proceed();
}
public int oneObjectArg(ProceedingJoinPoint pjp, Object bean) throws Throwable {
this.collaborator.oneObjectArg(bean);
return ((Integer) pjp.proceed()).intValue();
}
public void oneIntAndOneObject(ProceedingJoinPoint pjp, int x , Object o) throws Throwable {
this.collaborator.oneIntAndOneObject(x,o);
pjp.proceed();
}
public int justJoinPoint(ProceedingJoinPoint pjp) throws Throwable {
this.collaborator.justJoinPoint(pjp.getSignature().getName());
return ((Integer) pjp.proceed()).intValue();
}
/**
* Collaborator interface that makes it easy to test this aspect
* is working as expected through mocking.
*/
public interface AroundAdviceBindingCollaborator {
void oneIntArg(int x);
void oneObjectArg(Object o);
void oneIntAndOneObject(int x, Object o);
void justJoinPoint(String s);
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beforeAdviceBindingTests" ref="testAspect">
<aop:around method="oneIntArg" pointcut="execution(* setAge(int)) and args(age)" />
<aop:around method="oneObjectArg" pointcut="execution(* getAge()) and target(bean)"/>
<aop:around method="oneIntAndOneObject"
pointcut="execution(* setAge(..)) and args(age) and this(bean)" arg-names="thisJoinPoint,age,bean"/>
<aop:around method="justJoinPoint" pointcut="execution(* getAge())"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AroundAdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.aop.support.AopUtils;
/**
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class AroundAdviceCircularTests extends AroundAdviceBindingTests {
@Test
public void testBothBeansAreProxies() {
Object tb = ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(tb));
Object tb2 = ctx.getBean("testBean2");
assertTrue(AopUtils.isAopProxy(tb2));
}
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beforeAdviceBindingTests" ref="testAspect">
<aop:around method="oneIntArg" pointcut="execution(* setAge(int)) and args(age)" />
<aop:around method="oneObjectArg" pointcut="execution(* getAge()) and target(bean)"/>
<aop:around method="oneIntAndOneObject"
pointcut="execution(* setAge(..)) and args(age) and this(bean)" arg-names="thisJoinPoint,age,bean"/>
<aop:around method="justJoinPoint" pointcut="execution(* getAge())"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AroundAdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean">
<property name="spouse" ref="testBean2"/>
</bean>
<bean id="testBean2" class="org.springframework.beans.TestBean" autowire-candidate="false">
<property name="spouse" ref="testBean"/>
</bean>
</beans>

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.fail;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.ITestBean;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.Ordered;
/**
* @author Adrian Colyer
* @author Chris Beams
*/
public final class AspectAndAdvicePrecedenceTests {
private PrecedenceTestAspect highPrecedenceAspect;
private PrecedenceTestAspect lowPrecedenceAspect;
private SimpleSpringBeforeAdvice highPrecedenceSpringAdvice;
private SimpleSpringBeforeAdvice lowPrecedenceSpringAdvice;
private ITestBean testBean;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
highPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("highPrecedenceAspect");
lowPrecedenceAspect = (PrecedenceTestAspect) ctx.getBean("lowPrecedenceAspect");
highPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("highPrecedenceSpringAdvice");
lowPrecedenceSpringAdvice = (SimpleSpringBeforeAdvice) ctx.getBean("lowPrecedenceSpringAdvice");
testBean = (ITestBean) ctx.getBean("testBean");
}
// ========== end of test case set up, start of tests proper ===================
@Test
public void testAdviceOrder() {
PrecedenceTestAspect.Collaborator collaborator = new PrecedenceVerifyingCollaborator();
this.highPrecedenceAspect.setCollaborator(collaborator);
this.lowPrecedenceAspect.setCollaborator(collaborator);
this.highPrecedenceSpringAdvice.setCollaborator(collaborator);
this.lowPrecedenceSpringAdvice.setCollaborator(collaborator);
this.testBean.getAge();
}
private static class PrecedenceVerifyingCollaborator implements PrecedenceTestAspect.Collaborator {
private static final String[] EXPECTED = {
// this order confirmed by running the same aspects (minus the Spring AOP advisors)
// through AspectJ...
"beforeAdviceOne(highPrecedenceAspect)", // 1
"beforeAdviceTwo(highPrecedenceAspect)", // 2
"aroundAdviceOne(highPrecedenceAspect)", // 3, before proceed
"aroundAdviceTwo(highPrecedenceAspect)", // 4, before proceed
"beforeAdviceOne(highPrecedenceSpringAdvice)", // 5
"beforeAdviceOne(lowPrecedenceSpringAdvice)", // 6
"beforeAdviceOne(lowPrecedenceAspect)", // 7
"beforeAdviceTwo(lowPrecedenceAspect)", // 8
"aroundAdviceOne(lowPrecedenceAspect)", // 9, before proceed
"aroundAdviceTwo(lowPrecedenceAspect)", // 10, before proceed
"aroundAdviceTwo(lowPrecedenceAspect)", // 11, after proceed
"aroundAdviceOne(lowPrecedenceAspect)", // 12, after proceed
"afterAdviceOne(lowPrecedenceAspect)", // 13
"afterAdviceTwo(lowPrecedenceAspect)", // 14
"aroundAdviceTwo(highPrecedenceAspect)", // 15, after proceed
"aroundAdviceOne(highPrecedenceAspect)", // 16, after proceed
"afterAdviceOne(highPrecedenceAspect)", // 17
"afterAdviceTwo(highPrecedenceAspect)" // 18
};
private int adviceInvocationNumber = 0;
private void checkAdvice(String whatJustHappened) {
//System.out.println("[" + adviceInvocationNumber + "] " + whatJustHappened + " ==> " + EXPECTED[adviceInvocationNumber]);
if (adviceInvocationNumber > (EXPECTED.length - 1)) {
fail("Too many advice invocations, expecting " + EXPECTED.length
+ " but had " + adviceInvocationNumber);
}
String expecting = EXPECTED[adviceInvocationNumber++];
if (!whatJustHappened.equals(expecting)) {
fail("Expecting '" + expecting + "' on advice invocation " + adviceInvocationNumber +
" but got '" + whatJustHappened + "'");
}
}
public void beforeAdviceOne(String beanName) {
checkAdvice("beforeAdviceOne(" + beanName + ")");
}
public void beforeAdviceTwo(String beanName) {
checkAdvice("beforeAdviceTwo(" + beanName + ")");
}
public void aroundAdviceOne(String beanName) {
checkAdvice("aroundAdviceOne(" + beanName + ")");
}
public void aroundAdviceTwo(String beanName) {
checkAdvice("aroundAdviceTwo(" + beanName + ")");
}
public void afterAdviceOne(String beanName) {
checkAdvice("afterAdviceOne(" + beanName + ")");
}
public void afterAdviceTwo(String beanName) {
checkAdvice("afterAdviceTwo(" + beanName + ")");
}
}
}
class PrecedenceTestAspect implements BeanNameAware, Ordered {
private String name;
private int order = Ordered.LOWEST_PRECEDENCE;
private Collaborator collaborator;
public void setBeanName(String name) {
this.name = name;
}
public void setOrder(int order) {
this.order = order;
}
public int getOrder() {
return order;
}
public void setCollaborator(Collaborator collaborator) {
this.collaborator = collaborator;
}
public void beforeAdviceOne() {
this.collaborator.beforeAdviceOne(this.name);
}
public void beforeAdviceTwo() {
this.collaborator.beforeAdviceTwo(this.name);
}
public int aroundAdviceOne(ProceedingJoinPoint pjp) {
int ret = -1;
this.collaborator.aroundAdviceOne(this.name);
try {
ret = ((Integer)pjp.proceed()).intValue();
}
catch(Throwable t) { throw new RuntimeException(t); }
this.collaborator.aroundAdviceOne(this.name);
return ret;
}
public int aroundAdviceTwo(ProceedingJoinPoint pjp) {
int ret = -1;
this.collaborator.aroundAdviceTwo(this.name);
try {
ret = ((Integer)pjp.proceed()).intValue();
}
catch(Throwable t) {throw new RuntimeException(t);}
this.collaborator.aroundAdviceTwo(this.name);
return ret;
}
public void afterAdviceOne() {
this.collaborator.afterAdviceOne(this.name);
}
public void afterAdviceTwo() {
this.collaborator.afterAdviceTwo(this.name);
}
public interface Collaborator {
void beforeAdviceOne(String beanName);
void beforeAdviceTwo(String beanName);
void aroundAdviceOne(String beanName);
void aroundAdviceTwo(String beanName);
void afterAdviceOne(String beanName);
void afterAdviceTwo(String beanName);
}
}
class SimpleSpringBeforeAdvice implements MethodBeforeAdvice, BeanNameAware {
private PrecedenceTestAspect.Collaborator collaborator;
private String name;
/* (non-Javadoc)
* @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*/
public void before(Method method, Object[] args, Object target)
throws Throwable {
this.collaborator.beforeAdviceOne(this.name);
}
public void setCollaborator(PrecedenceTestAspect.Collaborator collaborator) {
this.collaborator = collaborator;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
*/
public void setBeanName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:advisor id="lowPrecedenceAdvisor"
advice-ref="lowPrecedenceSpringAdvice"
pointcut="execution(* getAge(..))"
order="900"/>
<aop:advisor id="highPrecedenceAdvisor"
advice-ref="highPrecedenceSpringAdvice"
pointcut="execution(* getAge(..))"
order="90"/>
<aop:aspect ref="lowPrecedenceAspect" order="1000">
<aop:before
method="beforeAdviceOne"
pointcut="execution(* getAge())"/>
<aop:before
method="beforeAdviceTwo"
pointcut="execution(* getAge())"/>
<aop:around
method="aroundAdviceOne"
pointcut="execution(* getAge())"/>
<aop:around
method="aroundAdviceTwo"
pointcut="execution(* getAge())"/>
<aop:after-returning
method="afterAdviceOne"
pointcut="execution(* getAge())"/>
<aop:after-returning
method="afterAdviceTwo"
pointcut="execution(* getAge())"/>
</aop:aspect>
<aop:aspect ref="highPrecedenceAspect">
<aop:before
method="beforeAdviceOne"
pointcut="execution(* getAge())"/>
<aop:before
method="beforeAdviceTwo"
pointcut="execution(* getAge())"/>
<aop:around
method="aroundAdviceOne"
pointcut="execution(* getAge())"/>
<aop:around
method="aroundAdviceTwo"
pointcut="execution(* getAge())"/>
<aop:after-returning
method="afterAdviceOne"
pointcut="execution(* getAge())"/>
<aop:after-returning
method="afterAdviceTwo"
pointcut="execution(* getAge())"/>
</aop:aspect>
</aop:config>
<bean id="highPrecedenceSpringAdvice" class="org.springframework.aop.aspectj.SimpleSpringBeforeAdvice"/>
<bean id="lowPrecedenceSpringAdvice" class="org.springframework.aop.aspectj.SimpleSpringBeforeAdvice"/>
<bean id="highPrecedenceAspect" class="org.springframework.aop.aspectj.PrecedenceTestAspect">
<property name="order" value="10"/>
</bean>
<bean id="lowPrecedenceAspect" class="org.springframework.aop.aspectj.PrecedenceTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertEquals;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.ITestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Rob Harrop
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class AspectJExpressionPointcutAdvisorTests {
private ITestBean testBean;
private CallCountingInterceptor interceptor;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean = (ITestBean) ctx.getBean("testBean");
interceptor = (CallCountingInterceptor) ctx.getBean("interceptor");
}
@Test
public void testPointcutting() {
assertEquals("Count should be 0", 0, interceptor.getCount());
testBean.getSpouses();
assertEquals("Count should be 1", 1, interceptor.getCount());
testBean.getSpouse();
assertEquals("Count should be 1", 1, interceptor.getCount());
}
}
class CallCountingInterceptor implements MethodInterceptor {
private int count;
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
count++;
return methodInvocation.proceed();
}
public int getCount() {
return count;
}
public void reset() {
this.count = 0;
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="proxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
<bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="expression"
value="execution(org.springframework.beans.ITestBean[] org.springframework.beans.ITestBean.*(..))"/>
<property name="advice" ref="interceptor"/>
</bean>
<bean id="interceptor" class="org.springframework.aop.aspectj.CallCountingInterceptor"/>
</beans>

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Test for correct application of the bean() PCD for &#64;AspectJ-based aspects.
*
* @author Ramnivas Laddad
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class BeanNamePointcutAtAspectTests {
private ITestBean testBean1;
private ITestBean testBean2;
private ITestBean testBean3;
private CounterAspect counterAspect;
@org.junit.Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
counterAspect = (CounterAspect) ctx.getBean("counterAspect");
testBean1 = (ITestBean) ctx.getBean("testBean1");
testBean2 = (ITestBean) ctx.getBean("testBean2");
testBean3 = (ITestBean) ctx.getBean("testBean3");
}
@Test
public void testMatchingBeanName() {
assertTrue("Expected a proxy", testBean1 instanceof Advised);
// Call two methods to test for SPR-3953-like condition
testBean1.setAge(20);
testBean1.setName("");
assertEquals(2 /*TODO: make this 3 when upgrading to AspectJ 1.6.0 and advice in CounterAspect are uncommented*/, counterAspect.count);
}
@Test
public void testNonMatchingBeanName() {
assertFalse("Didn't expect a proxy", testBean3 instanceof Advised);
testBean3.setAge(20);
assertEquals(0, counterAspect.count);
}
@Test
public void testProgrammaticProxyCreation() {
ITestBean testBean = new TestBean();
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(testBean);
CounterAspect myCounterAspect = new CounterAspect();
factory.addAspect(myCounterAspect);
ITestBean proxyTestBean = factory.getProxy();
assertTrue("Expected a proxy", proxyTestBean instanceof Advised);
proxyTestBean.setAge(20);
assertEquals("Programmatically created proxy shouldn't match bean()", 0, myCounterAspect.count);
}
}
@Aspect
class CounterAspect {
int count;
@Before("execution(* set*(..)) && bean(testBean1)")
public void increment1ForAnonymousPointcut() {
count++;
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy/>
<bean id="testBean1" class="org.springframework.beans.TestBean"/>
<bean id="testBean2" class="org.springframework.beans.TestBean"/>
<bean id="testBean3" class="org.springframework.beans.TestBean"/>
<bean id="counterAspect" class="org.springframework.aop.aspectj.CounterAspect"/>
</beans>

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.ITestBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Test for correct application of the bean() PCD for XML-based AspectJ aspects.
*
* @author Ramnivas Laddad
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class BeanNamePointcutTests {
private ITestBean testBean1;
private ITestBean testBean2;
private ITestBean testBeanContainingNestedBean;
private Map<?, ?> testFactoryBean1;
private Map<?, ?> testFactoryBean2;
private Counter counterAspect;
private ITestBean interceptThis;
private ITestBean dontInterceptThis;
private TestInterceptor testInterceptor;
private ClassPathXmlApplicationContext ctx;
@Before
public void setUp() {
ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean1 = (ITestBean) ctx.getBean("testBean1");
testBean2 = (ITestBean) ctx.getBean("testBean2");
testBeanContainingNestedBean = (ITestBean) ctx.getBean("testBeanContainingNestedBean");
testFactoryBean1 = (Map<?, ?>) ctx.getBean("testFactoryBean1");
testFactoryBean2 = (Map<?, ?>) ctx.getBean("testFactoryBean2");
counterAspect = (Counter) ctx.getBean("counterAspect");
interceptThis = (ITestBean) ctx.getBean("interceptThis");
dontInterceptThis = (ITestBean) ctx.getBean("dontInterceptThis");
testInterceptor = (TestInterceptor) ctx.getBean("testInterceptor");
counterAspect.reset();
}
// We don't need to test all combination of pointcuts due to BeanNamePointcutMatchingTests
@Test
public void testMatchingBeanName() {
assertTrue("Matching bean must be advised (proxied)", this.testBean1 instanceof Advised);
// Call two methods to test for SPR-3953-like condition
this.testBean1.setAge(20);
this.testBean1.setName("");
assertEquals("Advice not executed: must have been", 2, this.counterAspect.getCount());
}
@Test
public void testNonMatchingBeanName() {
assertFalse("Non-matching bean must *not* be advised (proxied)", this.testBean2 instanceof Advised);
this.testBean2.setAge(20);
assertEquals("Advice must *not* have been executed", 0, this.counterAspect.getCount());
}
@Test
public void testNonMatchingNestedBeanName() {
assertFalse("Non-matching bean must *not* be advised (proxied)", this.testBeanContainingNestedBean.getDoctor() instanceof Advised);
}
@Test
public void testMatchingFactoryBeanObject() {
assertTrue("Matching bean must be advised (proxied)", this.testFactoryBean1 instanceof Advised);
assertEquals("myValue", this.testFactoryBean1.get("myKey"));
assertEquals("myValue", this.testFactoryBean1.get("myKey"));
assertEquals("Advice not executed: must have been", 2, this.counterAspect.getCount());
FactoryBean<?> fb = (FactoryBean<?>) ctx.getBean("&testFactoryBean1");
assertTrue("FactoryBean itself must *not* be advised", !(fb instanceof Advised));
}
@Test
public void testMatchingFactoryBeanItself() {
assertTrue("Matching bean must *not* be advised (proxied)", !(this.testFactoryBean2 instanceof Advised));
FactoryBean<?> fb = (FactoryBean<?>) ctx.getBean("&testFactoryBean2");
assertTrue("FactoryBean itself must be advised", fb instanceof Advised);
assertTrue(Map.class.isAssignableFrom(fb.getObjectType()));
assertTrue(Map.class.isAssignableFrom(fb.getObjectType()));
assertEquals("Advice not executed: must have been", 2, this.counterAspect.getCount());
}
@Test
public void testPointcutAdvisorCombination() {
assertTrue("Matching bean must be advised (proxied)", this.interceptThis instanceof Advised);
assertFalse("Non-matching bean must *not* be advised (proxied)", this.dontInterceptThis instanceof Advised);
interceptThis.setAge(20);
assertEquals(1, testInterceptor.interceptionCount);
dontInterceptThis.setAge(20);
assertEquals(1, testInterceptor.interceptionCount);
}
public static class TestInterceptor implements MethodBeforeAdvice {
private int interceptionCount;
public void before(Method method, Object[] args, Object target) throws Throwable {
interceptionCount++;
}
}
}

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beanNameMatchingTest" ref="counterAspect">
<aop:pointcut id="bean1Operation" expression="execution(* set*(..)) and bean(myBean) and !bean(foo)"/>
<aop:before pointcut-ref="bean1Operation" method="increment()"/>
<aop:pointcut id="nestedBeanOperation" expression="execution(* getCompany(..)) and bean(testBean*)"/>
<aop:before pointcut-ref="nestedBeanOperation" method="increment()"/>
<aop:pointcut id="factoryBean1Operation" expression="bean(testFactoryBean1)"/>
<aop:before pointcut-ref="factoryBean1Operation" method="increment()"/>
<aop:pointcut id="factoryBean2Operation" expression="bean(&amp;testFactoryBean2)"/>
<aop:before pointcut-ref="factoryBean2Operation" method="increment()"/>
</aop:aspect>
</aop:config>
<bean id="testBean1" name="myBean" class="org.springframework.beans.TestBean"/>
<bean id="testBean2" class="org.springframework.beans.TestBean"/>
<bean id="testBeanContainingNestedBean" class="org.springframework.beans.TestBean">
<property name="doctor">
<bean class="org.springframework.beans.NestedTestBean"/>
</property>
</bean>
<bean id="testFactoryBean1" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="myKey" value="myValue"/>
</map>
</property>
</bean>
<bean id="testFactoryBean2" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="myKey" value="myValue"/>
</map>
</property>
</bean>
<bean id="counterAspect" class="org.springframework.aop.aspectj.Counter"/>
<aop:config>
<aop:advisor pointcut="bean(*This) and !bean(dont*)" advice-ref="testInterceptor"/>
</aop:config>
<bean id="interceptThis" class="org.springframework.beans.TestBean"/>
<bean id="dontInterceptThis" class="org.springframework.beans.TestBean"/>
<bean id="testInterceptor" class="org.springframework.aop.aspectj.BeanNamePointcutTests$TestInterceptor"/>
</beans>

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.AdviceBindingTestAspect.AdviceBindingCollaborator;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for various parameter binding scenarios with before advice.
*
* @author Adrian Colyer
* @author Rod Johnson
* @author Chris Beams
*/
public final class BeforeAdviceBindingTests {
private AdviceBindingCollaborator mockCollaborator;
private ITestBean testBeanProxy;
private TestBean testBeanTarget;
protected String getConfigPath() {
return "before-advice-tests.xml";
}
@Before
public void setUp() throws Exception {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBeanProxy = (ITestBean) ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(testBeanProxy));
// we need the real target too, not just the proxy...
testBeanTarget = (TestBean) ((Advised) testBeanProxy).getTargetSource().getTarget();
AdviceBindingTestAspect beforeAdviceAspect = (AdviceBindingTestAspect) ctx.getBean("testAspect");
mockCollaborator = createNiceMock(AdviceBindingCollaborator.class);
beforeAdviceAspect.setCollaborator(mockCollaborator);
}
@Test
public void testOneIntArg() {
mockCollaborator.oneIntArg(5);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testOneObjectArgBoundToProxyUsingThis() {
mockCollaborator.oneObjectArg(this.testBeanProxy);
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testOneIntAndOneObjectArgs() {
mockCollaborator.oneIntAndOneObject(5,this.testBeanTarget);
replay(mockCollaborator);
testBeanProxy.setAge(5);
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPoint() {
mockCollaborator.needsJoinPoint("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
@Test
public void testNeedsJoinPointStaticPart() {
mockCollaborator.needsJoinPointStaticPart("getAge");
replay(mockCollaborator);
testBeanProxy.getAge();
verify(mockCollaborator);
}
}
class AuthenticationLogger {
public void logAuthenticationAttempt(String username) {
System.out.println("User [" + username + "] attempting to authenticate");
}
}
class SecurityManager {
public boolean authenticate(String username, String password) {
return false;
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beforeAdviceBindingTests" ref="testAspect">
<aop:before method="oneIntArg" pointcut="execution(* setAge(int)) and args(age)"/>
<aop:before method="oneObjectArg" pointcut="execution(* getAge()) and this(bean)"/>
<aop:before method="oneIntAndOneObject"
pointcut="execution(* setAge(..)) and args(age) and target(bean)" arg-names="age,bean"/>
<aop:before method="needsJoinPoint" pointcut="execution(* getAge())"/>
<aop:before method="needsJoinPointStaticPart" pointcut="execution(* getAge())"/>
</aop:aspect>
<!-- variation with external pointcut reference -->
<aop:aspect ref="authenticationLogger">
<aop:pointcut id="authenticationMethodWithString"
expression="execution(boolean *..SecurityManager.authenticate(..)) and args(username,java.lang.String)"/>
<aop:before pointcut-ref="authenticationMethodWithString"
method="logAuthenticationAttempt(java.lang.String)"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.AdviceBindingTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
<bean id="authenticationLogger" class="org.springframework.aop.aspectj.AuthenticationLogger"/>
</beans>

View File

@@ -0,0 +1,192 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertTrue;
import java.io.Serializable;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Adrian Colyer
* @author Chris Beams
*/
public final class DeclarationOrderIndependenceTests {
private TopsyTurvyAspect aspect;
private TopsyTurvyTarget target;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
aspect = (TopsyTurvyAspect) ctx.getBean("topsyTurvyAspect");
target = (TopsyTurvyTarget) ctx.getBean("topsyTurvyTarget");
}
@Test
public void testTargetIsSerializable() {
assertTrue("target bean is serializable",this.target instanceof Serializable);
}
@Test
public void testTargetIsBeanNameAware() {
assertTrue("target bean is bean name aware",this.target instanceof BeanNameAware);
}
@Test
public void testBeforeAdviceFiringOk() {
AspectCollaborator collab = new AspectCollaborator();
this.aspect.setCollaborator(collab);
this.target.doSomething();
assertTrue("before advice fired",collab.beforeFired);
}
@Test
public void testAroundAdviceFiringOk() {
AspectCollaborator collab = new AspectCollaborator();
this.aspect.setCollaborator(collab);
this.target.getX();
assertTrue("around advice fired",collab.aroundFired);
}
@Test
public void testAfterReturningFiringOk() {
AspectCollaborator collab = new AspectCollaborator();
this.aspect.setCollaborator(collab);
this.target.getX();
assertTrue("after returning advice fired",collab.afterReturningFired);
}
/** public visibility is required */
public static class BeanNameAwareMixin implements BeanNameAware {
private String beanName;
/* (non-Javadoc)
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
*/
public void setBeanName(String name) {
this.beanName = name;
}
}
/** public visibility is required */
@SuppressWarnings("serial")
public static class SerializableMixin implements Serializable {
}
}
class TopsyTurvyAspect {
interface Collaborator {
void beforeAdviceFired();
void afterReturningAdviceFired();
void aroundAdviceFired();
}
private Collaborator collaborator;
public void setCollaborator(Collaborator collaborator) {
this.collaborator = collaborator;
}
public void before() {
this.collaborator.beforeAdviceFired();
}
public void afterReturning() {
this.collaborator.afterReturningAdviceFired();
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object ret = pjp.proceed();
this.collaborator.aroundAdviceFired();
return ret;
}
}
interface TopsyTurvyTarget {
public abstract void doSomething();
public abstract int getX();
}
class TopsyTurvyTargetImpl implements TopsyTurvyTarget {
private int x = 5;
/* (non-Javadoc)
* @see org.springframework.aop.aspectj.TopsyTurvyTarget#doSomething()
*/
public void doSomething() {
this.x = 10;
}
/* (non-Javadoc)
* @see org.springframework.aop.aspectj.TopsyTurvyTarget#getX()
*/
public int getX() {
return x;
}
}
class AspectCollaborator implements TopsyTurvyAspect.Collaborator {
public boolean afterReturningFired = false;
public boolean aroundFired = false;
public boolean beforeFired = false;
/* (non-Javadoc)
* @see org.springframework.aop.aspectj.TopsyTurvyAspect.Collaborator#afterReturningAdviceFired()
*/
public void afterReturningAdviceFired() {
this.afterReturningFired = true;
}
/* (non-Javadoc)
* @see org.springframework.aop.aspectj.TopsyTurvyAspect.Collaborator#aroundAdviceFired()
*/
public void aroundAdviceFired() {
this.aroundFired = true;
}
/* (non-Javadoc)
* @see org.springframework.aop.aspectj.TopsyTurvyAspect.Collaborator#beforeAdviceFired()
*/
public void beforeAdviceFired() {
this.beforeFired = true;
}
}

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="topsyTurvyAspect" class="org.springframework.aop.aspectj.TopsyTurvyAspect"/>
<bean id="topsyTurvyTarget" class="org.springframework.aop.aspectj.TopsyTurvyTargetImpl"/>
<aop:config>
<aop:aspect id="myAspect" ref="topsyTurvyAspect">
<aop:before pointcut-ref="pc1"
method="before"/>
<aop:declare-parents
types-matching="*..TopsyTurvyTarget+"
implement-interface="java.io.Serializable"
default-impl="org.springframework.aop.aspectj.DeclarationOrderIndependenceTests$SerializableMixin"/>
<aop:after-returning pointcut-ref="pc2" method="afterReturning"/>
<aop:pointcut id="pc1" expression="execution(* *..do*(..))"/>
<aop:around pointcut-ref="pc2"
method="around"/>
<aop:pointcut id="pc2" expression="execution(* *..TopsyTurvyTarget+.get*(..))"/>
<aop:declare-parents
types-matching="*..TopsyTurvyTarget+"
implement-interface="org.springframework.beans.factory.BeanNameAware"
default-impl="org.springframework.aop.aspectj.DeclarationOrderIndependenceTests$BeanNameAwareMixin"/>
</aop:aspect>
</aop:config>
</beans>

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Ramnivas Laddad
* @author Chris Beams
*/
public class DeclareParentsDelegateRefTests {
protected NoMethodsBean noMethodsBean;
protected Counter counter;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
noMethodsBean = (NoMethodsBean) ctx.getBean("noMethodsBean");
counter = (Counter) ctx.getBean("counter");
counter.reset();
}
@Test
public void testIntroductionWasMade() {
assertTrue("Introduction must have been made", noMethodsBean instanceof ICounter);
}
@Test
public void testIntroductionDelegation() {
((ICounter)noMethodsBean).increment();
assertEquals("Delegate's counter should be updated", 1, counter.getCount());
}
}
interface NoMethodsBean {
}
class NoMethodsBeanImpl implements NoMethodsBean {
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:config>
<aop:aspect id="testAspect">
<aop:declare-parents
types-matching="org.springframework.aop.aspectj.NoMethodsBean+"
implement-interface="org.springframework.aop.aspectj.ICounter"
delegate-ref="counter"
/>
</aop:aspect>
</aop:config>
<bean id="noMethodsBean" class="org.springframework.aop.aspectj.NoMethodsBeanImpl"/>
<bean id="counter" class="org.springframework.aop.aspectj.Counter"/>
</beans>

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.mixin.Lockable;
/**
* @author Rod Johnson
* @author Chris Beams
*/
public final class DeclareParentsTests {
private ITestBean testBeanProxy;
private TestBean testBeanTarget;
private ApplicationContext ctx;
@Before
public void setUp() throws Exception {
ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBeanProxy = (ITestBean) ctx.getBean("testBean");
assertTrue(AopUtils.isAopProxy(testBeanProxy));
// we need the real target too, not just the proxy...
testBeanTarget = (TestBean) ((Advised) testBeanProxy).getTargetSource().getTarget();
}
@Test
public void testIntroductionWasMade() {
assertTrue("Introduction must have been made", testBeanProxy instanceof Lockable);
}
// TODO if you change type pattern from org.springframework.beans..*
// to org.springframework..* it also matches introduction.
// Perhaps generated advisor bean definition could be made to depend
// on the introduction, in which case this would not be a problem.
@Test
public void testLockingWorks() {
Object introductionObject = ctx.getBean("introduction");
assertFalse("Introduction should not be proxied", AopUtils.isAopProxy(introductionObject));
Lockable lockable = (Lockable) testBeanProxy;
assertFalse(lockable.locked());
// Invoke a non-advised method
testBeanProxy.getAge();
testBeanProxy.setName("");
lockable.lock();
try {
testBeanProxy.setName(" ");
fail("Should be locked");
}
catch (IllegalStateException ex) {
// expected
}
}
}
class NonAnnotatedMakeLockable {
public void checkNotLocked(Lockable mixin) {
if (mixin.locked()) {
throw new IllegalStateException("locked");
}
}
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beforeAdviceBindingTests" ref="introduction">
<aop:declare-parents
types-matching="org.springframework.beans..*"
implement-interface="test.mixin.Lockable"
default-impl="test.mixin.DefaultLockable"
/>
<aop:before
method="checkNotLocked"
pointcut="execution(* set*(*)) and this(mixin)"
arg-names="mixin"
/>
</aop:aspect>
</aop:config>
<bean id="introduction" class="org.springframework.aop.aspectj.NonAnnotatedMakeLockable"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Test;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests to check if the first implicit join point argument is correctly processed.
* See SPR-3723 for more details.
*
* @author Ramnivas Laddad
* @author Chris Beams
*/
public final class ImplicitJPArgumentMatchingAtAspectJTests {
@Test
public void testAspect() {
// nothing to really test; it is enough if we don't get error while creating app context
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
}
@Aspect
static class CounterAtAspectJAspect {
@Around(value="execution(* org.springframework.beans.TestBean.*(..)) and this(bean) and args(argument)",
argNames="bean,argument")
public void increment(ProceedingJoinPoint pjp, TestBean bean, Object argument) throws Throwable {
pjp.proceed();
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="testBean" class="org.springframework.beans.TestBean">
<property name="name" value="aTestBean"/>
</bean>
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="counterAtAspectJAspect"/>
</aop:aspectj-autoproxy>
<bean id="counterAtAspectJAspect"
class="org.springframework.aop.aspectj.ImplicitJPArgumentMatchingAtAspectJTests$CounterAtAspectJAspect"/>
</beans>

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests to check if the first implicit join point argument is correctly processed.
* See SPR-3723 for more details.
*
* @author Ramnivas Laddad
* @author Chris Beams
*/
public final class ImplicitJPArgumentMatchingTests {
@Test
public void testAspect() {
// nothing to really test; it is enough if we don't get error while creating app context
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
}
static class CounterAspect {
public void increment(ProceedingJoinPoint pjp, Object bean, Object argument) throws Throwable {
pjp.proceed();
}
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config proxy-target-class="true">
<aop:aspect ref="counterAspect">
<aop:pointcut id="anyOperation"
expression="execution(* org.springframework.beans.TestBean.*(..)) and this(bean) and args(argument)"/>
<aop:around pointcut-ref="anyOperation" method="increment" arg-names="bean,argument"/>
</aop:aspect>
</aop:config>
<bean id="testBean" class="org.springframework.beans.TestBean">
<property name="name" value="aTestBean"/>
</bean>
<bean id="counterAspect"
class="org.springframework.aop.aspectj.ImplicitJPArgumentMatchingTests$CounterAspect"/>
</beans>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="ambiguousAdviceTest" ref="testAspect">
<aop:pointcut id="setter" expression="execution(* setName(..)) and args(name)"/>
<aop:before pointcut-ref="setter" method="myBeforeAdvice"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.OverloadedAdviceTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Integration tests for overloaded advice.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public final class OverloadedAdviceTests {
@Test
public void testExceptionOnConfigParsingWithMismatchedAdviceMethod() {
try {
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
}
catch (BeanCreationException ex) {
Throwable cause = ex.getRootCause();
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
assertTrue("invalidAbsoluteTypeName should be detected by AJ",
cause.getMessage().indexOf("invalidAbsoluteTypeName") != -1);
}
}
@Test
public void testExceptionOnConfigParsingWithAmbiguousAdviceMethod() {
try {
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-ambiguous.xml", getClass());
}
catch (BeanCreationException ex) {
Throwable cause = ex.getRootCause();
assertTrue("Should be IllegalArgumentException", cause instanceof IllegalArgumentException);
assertTrue("Cannot resolve method 'myBeforeAdvice' to a unique method",
cause.getMessage().indexOf("Cannot resolve method 'myBeforeAdvice' to a unique method") != -1);
}
}
}
class OverloadedAdviceTestAspect {
public void myBeforeAdvice(String name) {
// no-op
}
public void myBeforeAdvice(int age) {
// no-op
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="overloadedAdviceTest" ref="testAspect">
<aop:pointcut id="setter" expression="execution(* setName(..)) and args(name)"/>
<aop:before pointcut-ref="setter" method="myBeforeAdvice(java.lang.String)"/>
<aop:before pointcut-ref="setter" method="myBeforeAdvice(int)"/>
</aop:aspect>
</aop:config>
<bean id="testAspect" class="org.springframework.aop.aspectj.OverloadedAdviceTestAspect"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@@ -0,0 +1,206 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.Ordered;
/**
* Test for SPR-3522. Arguments changed on a call to proceed should be
* visible to advice further down the invocation chain.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public final class ProceedTests {
private SimpleBean testBean;
private ProceedTestingAspect firstTestAspect;
private ProceedTestingAspect secondTestAspect;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean = (SimpleBean) ctx.getBean("testBean");
firstTestAspect = (ProceedTestingAspect) ctx.getBean("firstTestAspect");
secondTestAspect = (ProceedTestingAspect) ctx.getBean("secondTestAspect");
}
@Test
public void testSimpleProceedWithChangedArgs() {
this.testBean.setName("abc");
assertEquals("Name changed in around advice", "ABC", this.testBean.getName());
}
@Test
public void testGetArgsIsDefensive() {
this.testBean.setAge(5);
assertEquals("getArgs is defensive", 5, this.testBean.getAge());
}
@Test
public void testProceedWithArgsInSameAspect() {
this.testBean.setMyFloat(1.0F);
assertTrue("value changed in around advice", this.testBean.getMyFloat() > 1.9F);
assertTrue("changed value visible to next advice in chain", this.firstTestAspect.getLastBeforeFloatValue() > 1.9F);
}
@Test
public void testProceedWithArgsAcrossAspects() {
this.testBean.setSex("male");
assertEquals("value changed in around advice","MALE", this.testBean.getSex());
assertEquals("changed value visible to next before advice in chain","MALE", this.secondTestAspect.getLastBeforeStringValue());
assertEquals("changed value visible to next around advice in chain","MALE", this.secondTestAspect.getLastAroundStringValue());
}
}
interface SimpleBean {
void setName(String name);
String getName();
void setAge(int age);
int getAge();
void setMyFloat(float f);
float getMyFloat();
void setSex(String sex);
String getSex();
}
class SimpleBeanImpl implements SimpleBean {
private int age;
private float aFloat;
private String name;
private String sex;
public int getAge() {
return age;
}
public float getMyFloat() {
return aFloat;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public void setAge(int age) {
this.age = age;
}
public void setMyFloat(float f) {
this.aFloat = f;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
}
class ProceedTestingAspect implements Ordered {
private String lastBeforeStringValue;
private String lastAroundStringValue;
private float lastBeforeFloatValue;
private int order;
public void setOrder(int order) { this.order = order; }
public int getOrder() { return this.order; }
public Object capitalize(ProceedingJoinPoint pjp, String value) throws Throwable {
return pjp.proceed(new Object[] {value.toUpperCase()});
}
public Object doubleOrQuits(ProceedingJoinPoint pjp) throws Throwable {
int value = ((Integer) pjp.getArgs()[0]).intValue();
pjp.getArgs()[0] = new Integer(value * 2);
return pjp.proceed();
}
public Object addOne(ProceedingJoinPoint pjp, Float value) throws Throwable {
float fv = value.floatValue();
return pjp.proceed(new Object[] {new Float(fv + 1.0F)});
}
public void captureStringArgument(JoinPoint tjp, String arg) {
if (!tjp.getArgs()[0].equals(arg)) {
throw new IllegalStateException(
"argument is '" + arg + "', " +
"but args array has '" + tjp.getArgs()[0] + "'"
);
}
this.lastBeforeStringValue = arg;
}
public Object captureStringArgumentInAround(ProceedingJoinPoint pjp, String arg) throws Throwable {
if (!pjp.getArgs()[0].equals(arg)) {
throw new IllegalStateException(
"argument is '" + arg + "', " +
"but args array has '" + pjp.getArgs()[0] + "'");
}
this.lastAroundStringValue = arg;
return pjp.proceed();
}
public void captureFloatArgument(JoinPoint tjp, float arg) {
float tjpArg = ((Float) tjp.getArgs()[0]).floatValue();
if (Math.abs(tjpArg - arg) > 0.000001) {
throw new IllegalStateException(
"argument is '" + arg + "', " +
"but args array has '" + tjpArg + "'"
);
}
this.lastBeforeFloatValue = arg;
}
public String getLastBeforeStringValue() {
return this.lastBeforeStringValue;
}
public String getLastAroundStringValue() {
return this.lastAroundStringValue;
}
public float getLastBeforeFloatValue() {
return this.lastBeforeFloatValue;
}
}

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="aspectOne" ref="firstTestAspect">
<aop:around pointcut="execution(* setName(..)) and args(value)" method="capitalize"/>
<aop:around pointcut="execution(* setAge(..))" method="doubleOrQuits"/>
<aop:around pointcut="execution(* setMyFloat(..)) and args(value)" method="addOne"/>
<aop:before pointcut="execution(* setMyFloat(..)) and args(arg)" method="captureFloatArgument"/>
<aop:around pointcut="execution(* setSex(..)) and args(value)" method="capitalize"/>
</aop:aspect>
<aop:aspect id="aspectTwo" ref="secondTestAspect">
<aop:before pointcut="execution(* setSex(..)) and args(arg)" method="captureStringArgument"/>
<aop:around pointcut="execution(* setSex(..)) and args(arg)" method="captureStringArgumentInAround"/>
</aop:aspect>
</aop:config>
<bean id="testBean" class="org.springframework.aop.aspectj.SimpleBeanImpl"/>
<bean id="firstTestAspect" class="org.springframework.aop.aspectj.ProceedTestingAspect">
<property name="order" value="1"/>
</bean>
<bean id="secondTestAspect" class="org.springframework.aop.aspectj.ProceedTestingAspect">
<property name="order" value="2"/>
</bean>
</beans>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect ref="monitoringAspect">
<aop:before method="before" pointcut="execution(* increment*())" />
<aop:around method="around" pointcut="execution(* increment*())" />
</aop:aspect>
</aop:config>
<bean id="monitoringAspect" class="org.springframework.aop.aspectj.JoinPointMonitorAspect">
<property name="counter" ref="counter"/>
</bean>
<bean id="counter" class="org.springframework.aop.aspectj.Counter"/>
</beans>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="counter" class="org.springframework.aop.aspectj.Counter"/>
<aop:aspectj-autoproxy/>
<bean id="monitoringAspect" class="org.springframework.aop.aspectj.JoinPointMonitorAtAspectJAspect">
<property name="counter" ref="counter" />
</bean>
</beans>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy/>
<bean id="monitoringAspect"
class="org.springframework.aop.aspectj.JoinPointMonitorAtAspectJAspect">
<property name="counter" ref="counter" />
</bean>
<bean id="counter" class="org.springframework.aop.aspectj.Counter"/>
</beans>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="counter" class="org.springframework.aop.aspectj.Counter"/>
<aop:config>
<aop:aspect ref="monitoringAspect">
<aop:before method="before" pointcut="execution(* increment*())" />
<aop:around method="around" pointcut="execution(* increment*())" />
</aop:aspect>
</aop:config>
<bean id="monitoringAspect" class="org.springframework.aop.aspectj.JoinPointMonitorAspect" lazy-init="true">
<property name="counter" ref="counter"/>
</bean>
</beans>

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Check that an aspect that depends on another bean, where the referenced bean
* itself is advised by the same aspect, works correctly.
*
* @author Ramnivas Laddad
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class PropertyDependentAspectTests {
@Test
public void testPropertyDependentAspectWithPropertyDeclaredBeforeAdvice() throws Exception {
checkXmlAspect(getClass().getSimpleName() + "-before.xml");
}
@Test
public void testPropertyDependentAspectWithPropertyDeclaredAfterAdvice() throws Exception {
checkXmlAspect(getClass().getSimpleName() + "-after.xml");
}
@Test
public void testPropertyDependentAtAspectJAspectWithPropertyDeclaredBeforeAdvice() throws Exception {
checkAtAspectJAspect(getClass().getSimpleName() + "-atAspectJ-before.xml");
}
@Test
public void testPropertyDependentAtAspectJAspectWithPropertyDeclaredAfterAdvice() throws Exception {
checkAtAspectJAspect(getClass().getSimpleName() + "-atAspectJ-after.xml");
}
private void checkXmlAspect(String appContextFile) {
ApplicationContext context = new ClassPathXmlApplicationContext(appContextFile, getClass());
ICounter counter = (ICounter) context.getBean("counter");
assertTrue("Proxy didn't get created", counter instanceof Advised);
counter.increment();
JoinPointMonitorAspect callCountingAspect = (JoinPointMonitorAspect)context.getBean("monitoringAspect");
assertEquals("Advise didn't get executed", 1, callCountingAspect.beforeExecutions);
assertEquals("Advise didn't get executed", 1, callCountingAspect.aroundExecutions);
}
private void checkAtAspectJAspect(String appContextFile) {
ApplicationContext context = new ClassPathXmlApplicationContext(appContextFile, getClass());
ICounter counter = (ICounter) context.getBean("counter");
assertTrue("Proxy didn't get created", counter instanceof Advised);
counter.increment();
JoinPointMonitorAtAspectJAspect callCountingAspect = (JoinPointMonitorAtAspectJAspect)context.getBean("monitoringAspect");
assertEquals("Advise didn't get executed", 1, callCountingAspect.beforeExecutions);
assertEquals("Advise didn't get executed", 1, callCountingAspect.aroundExecutions);
}
}
class JoinPointMonitorAspect {
/**
* The counter property is purposefully not used in the aspect to avoid distraction
* from the main bug -- merely needing a dependency on an advised bean
* is sufficient to reproduce the bug.
*/
private ICounter counter;
int beforeExecutions;
int aroundExecutions;
public void before() {
beforeExecutions++;
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
aroundExecutions++;
return pjp.proceed();
}
public ICounter getCounter() {
return counter;
}
public void setCounter(ICounter counter) {
this.counter = counter;
}
}
@Aspect
class JoinPointMonitorAtAspectJAspect {
/* The counter property is purposefully not used in the aspect to avoid distraction
* from the main bug -- merely needing a dependency on an advised bean
* is sufficient to reproduce the bug.
*/
private ICounter counter;
int beforeExecutions;
int aroundExecutions;
@Before("execution(* increment*())")
public void before() {
beforeExecutions++;
}
@Around("execution(* increment*())")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
aroundExecutions++;
return pjp.proceed();
}
public ICounter getCounter() {
return counter;
}
public void setCounter(ICounter counter) {
this.counter = counter;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* See SPR-1682.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public final class SharedPointcutWithArgsMismatchTests {
private ToBeAdvised toBeAdvised;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
toBeAdvised = (ToBeAdvised) ctx.getBean("toBeAdvised");
}
@Test
public void testMismatchedArgBinding() {
this.toBeAdvised.foo("Hello");
}
}
class ToBeAdvised {
public void foo(String s) {
System.out.println(s);
}
}
class MyAspect {
public void doBefore(int x) {
System.out.println(x);
}
public void doBefore(String x) {
System.out.println(x);
}
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="beforeAdviceBindingTests" ref="testAspect">
<aop:pointcut id="foo" expression="execution(* foo(..)) and args(x)"/>
<aop:before pointcut-ref="foo" method="doBefore(int)"/>
<aop:before pointcut-ref="foo" method="doBefore(java.lang.String)"/>
</aop:aspect>
</aop:config>
<bean id="toBeAdvised" class="org.springframework.aop.aspectj.ToBeAdvised"/>
<bean id="testAspect" class="org.springframework.aop.aspectj.MyAspect"/>
</beans>

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.*;
import java.io.Serializable;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Adrian Colyer
* @author Chris Beams
*/
public final class SubtypeSensitiveMatchingTests {
private NonSerializableFoo nonSerializableBean;
private SerializableFoo serializableBean;
private Bar bar;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
nonSerializableBean = (NonSerializableFoo) ctx.getBean("testClassA");
serializableBean = (SerializableFoo) ctx.getBean("testClassB");
bar = (Bar) ctx.getBean("testClassC");
}
@Test
public void testBeansAreProxiedOnStaticMatch() {
assertTrue("bean with serializable type should be proxied",
this.serializableBean instanceof Advised);
}
@Test
public void testBeansThatDoNotMatchBasedSolelyOnRuntimeTypeAreNotProxied() {
assertFalse("bean with non-serializable type should not be proxied",
this.nonSerializableBean instanceof Advised);
}
@Test
public void testBeansThatDoNotMatchBasedOnOtherTestAreProxied() {
assertTrue("bean with args check should be proxied",
this.bar instanceof Advised);
}
}
//strange looking interfaces are just to set up certain test conditions...
interface NonSerializableFoo { void foo(); }
interface SerializableFoo extends Serializable { void foo(); }
class SubtypeMatchingTestClassA implements NonSerializableFoo {
public void foo() {}
}
@SuppressWarnings("serial")
class SubtypeMatchingTestClassB implements SerializableFoo {
public void foo() {}
}
interface Bar { void bar(Object o); }
class SubtypeMatchingTestClassC implements Bar {
public void bar(Object o) {}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect id="thisMatcher" ref="testAspect">
<aop:before pointcut="execution(* *(..)) and this(java.io.Serializable)" method="toString"/>
</aop:aspect>
<aop:aspect id="targetMatcher" ref="testAspect">
<aop:before pointcut="execution(* *(..)) and target(java.io.Serializable)" method="toString"/>
</aop:aspect>
<aop:aspect id="argsMatcher" ref="testAspect">
<aop:before pointcut="execution(* bar(..)) and args(java.io.Serializable)" method="toString"/>
</aop:aspect>
</aop:config>
<!-- should not be proxied -->
<bean id="testClassA" class="org.springframework.aop.aspectj.SubtypeMatchingTestClassA"/>
<!-- should be proxied -->
<bean id="testClassB" class="org.springframework.aop.aspectj.SubtypeMatchingTestClassB"/>
<!-- should be proxied -->
<bean id="testClassC" class="org.springframework.aop.aspectj.SubtypeMatchingTestClassC"/>
<bean id="testAspect" class="java.lang.Object"/>
</beans>

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertEquals;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests for target selection matching (see SPR-3783).
* Thanks to Tomasz Blachowicz for the bug report!
*
* @author Ramnivas Laddad
* @author Chris Beams
*/
public final class TargetPointcutSelectionTests {
public TestInterface testImpl1;
public TestInterface testImpl2;
public TestAspect testAspectForTestImpl1;
public TestAspect testAspectForAbstractTestImpl;
public TestInterceptor testInterceptor;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testImpl1 = (TestInterface) ctx.getBean("testImpl1");
testImpl2 = (TestInterface) ctx.getBean("testImpl2");
testAspectForTestImpl1 = (TestAspect) ctx.getBean("testAspectForTestImpl1");
testAspectForAbstractTestImpl = (TestAspect) ctx.getBean("testAspectForAbstractTestImpl");
testInterceptor = (TestInterceptor) ctx.getBean("testInterceptor");
testAspectForTestImpl1.count = 0;
testAspectForAbstractTestImpl.count = 0;
testInterceptor.count = 0;
}
@Test
public void testTargetSelectionForMatchedType() {
testImpl1.interfaceMethod();
assertEquals("Should have been advised by POJO advice for impl", 1, testAspectForTestImpl1.count);
assertEquals("Should have been advised by POJO advice for base type", 1, testAspectForAbstractTestImpl.count);
assertEquals("Should have been advised by advisor", 1, testInterceptor.count);
}
@Test
public void testTargetNonSelectionForMismatchedType() {
testImpl2.interfaceMethod();
assertEquals("Shouldn't have been advised by POJO advice for impl", 0, testAspectForTestImpl1.count);
assertEquals("Should have been advised by POJO advice for base type", 1, testAspectForAbstractTestImpl.count);
assertEquals("Shouldn't have been advised by advisor", 0, testInterceptor.count);
}
public static interface TestInterface {
public void interfaceMethod();
}
// Reproducing bug requires that the class specified in target() pointcut doesn't
// include the advised method's implementation (instead a base class should include it)
public static abstract class AbstractTestImpl implements TestInterface {
public void interfaceMethod() {
}
}
public static class TestImpl1 extends AbstractTestImpl {
}
public static class TestImpl2 extends AbstractTestImpl {
}
public static class TestAspect {
public int count;
public void increment() {
count++;
}
}
public static class TestInterceptor extends TestAspect implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
increment();
return mi.proceed();
}
}
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:advisor pointcut="target(org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestImpl1)"
advice-ref="testInterceptor"/>
<aop:aspect ref="testAspectForTestImpl1">
<aop:before pointcut="target(org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestImpl1)"
method="increment"/>
</aop:aspect>
<aop:aspect ref="testAspectForAbstractTestImpl">
<aop:before pointcut="target(org.springframework.aop.aspectj.TargetPointcutSelectionTests$AbstractTestImpl)"
method="increment"/>
</aop:aspect>
</aop:config>
<bean id="testImpl1" class="org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestImpl1"/>
<bean id="testImpl2" class="org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestImpl2"/>
<bean id="testAspectForTestImpl1" class="org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestAspect"/>
<bean id="testAspectForAbstractTestImpl" class="org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestAspect"/>
<bean id="testInterceptor" class="org.springframework.aop.aspectj.TargetPointcutSelectionTests$TestInterceptor"/>
</beans>

View File

@@ -0,0 +1,205 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertEquals;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Ramnivas Laddad
* @author Chris Beams
*/
public final class ThisAndTargetSelectionOnlyPointcutsAtAspectJTests {
public TestInterface testBean;
public TestInterface testAnnotatedClassBean;
public TestInterface testAnnotatedMethodBean;
protected Counter counter;
@org.junit.Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean = (TestInterface) ctx.getBean("testBean");
testAnnotatedClassBean = (TestInterface) ctx.getBean("testAnnotatedClassBean");
testAnnotatedMethodBean = (TestInterface) ctx.getBean("testAnnotatedMethodBean");
counter = (Counter) ctx.getBean("counter");
counter.reset();
}
@Test
public void testThisAsClassDoesNotMatch() {
testBean.doIt();
assertEquals(0, counter.thisAsClassCounter);
}
@Test
public void testThisAsInterfaceMatch() {
testBean.doIt();
assertEquals(1, counter.thisAsInterfaceCounter);
}
@Test
public void testTargetAsClassDoesMatch() {
testBean.doIt();
assertEquals(1, counter.targetAsClassCounter);
}
@Test
public void testTargetAsInterfaceMatch() {
testBean.doIt();
assertEquals(1, counter.targetAsInterfaceCounter);
}
@Test
public void testThisAsClassAndTargetAsClassCounterNotMatch() {
testBean.doIt();
assertEquals(0, counter.thisAsClassAndTargetAsClassCounter);
}
@Test
public void testThisAsInterfaceAndTargetAsInterfaceCounterMatch() {
testBean.doIt();
assertEquals(1, counter.thisAsInterfaceAndTargetAsInterfaceCounter);
}
@Test
public void testThisAsInterfaceAndTargetAsClassCounterMatch() {
testBean.doIt();
assertEquals(1, counter.thisAsInterfaceAndTargetAsInterfaceCounter);
}
@Test
public void testAtTargetClassAnnotationMatch() {
testAnnotatedClassBean.doIt();
assertEquals(1, counter.atTargetClassAnnotationCounter);
}
@Test
public void testAtAnnotationMethodAnnotationMatch() {
testAnnotatedMethodBean.doIt();
assertEquals(1, counter.atAnnotationMethodAnnotationCounter);
}
public static interface TestInterface {
public void doIt();
}
public static class TestImpl implements TestInterface {
public void doIt() {
}
}
@Retention(RetentionPolicy.RUNTIME)
public static @interface TestAnnotation {
}
@TestAnnotation
public static class AnnotatedClassTestImpl implements TestInterface {
public void doIt() {
}
}
public static class AnnotatedMethodTestImpl implements TestInterface {
@TestAnnotation
public void doIt() {
}
}
@Aspect
public static class Counter {
int thisAsClassCounter;
int thisAsInterfaceCounter;
int targetAsClassCounter;
int targetAsInterfaceCounter;
int thisAsClassAndTargetAsClassCounter;
int thisAsInterfaceAndTargetAsInterfaceCounter;
int thisAsInterfaceAndTargetAsClassCounter;
int atTargetClassAnnotationCounter;
int atAnnotationMethodAnnotationCounter;
public void reset() {
thisAsClassCounter = 0;
thisAsInterfaceCounter = 0;
targetAsClassCounter = 0;
targetAsInterfaceCounter = 0;
thisAsClassAndTargetAsClassCounter = 0;
thisAsInterfaceAndTargetAsInterfaceCounter = 0;
thisAsInterfaceAndTargetAsClassCounter = 0;
atTargetClassAnnotationCounter = 0;
atAnnotationMethodAnnotationCounter = 0;
}
@Before("this(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestImpl)")
public void incrementThisAsClassCounter() {
thisAsClassCounter++;
}
@Before("this(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestInterface)")
public void incrementThisAsInterfaceCounter() {
thisAsInterfaceCounter++;
}
@Before("target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestImpl)")
public void incrementTargetAsClassCounter() {
targetAsClassCounter++;
}
@Before("target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestInterface)")
public void incrementTargetAsInterfaceCounter() {
targetAsInterfaceCounter++;
}
@Before("this(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestImpl) " +
"&& target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestImpl)")
public void incrementThisAsClassAndTargetAsClassCounter() {
thisAsClassAndTargetAsClassCounter++;
}
@Before("this(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestInterface) " +
"&& target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestInterface)")
public void incrementThisAsInterfaceAndTargetAsInterfaceCounter() {
thisAsInterfaceAndTargetAsInterfaceCounter++;
}
@Before("this(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestInterface) " +
"&& target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestImpl)")
public void incrementThisAsInterfaceAndTargetAsClassCounter() {
thisAsInterfaceAndTargetAsClassCounter++;
}
@Before("@target(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestAnnotation)")
public void incrementAtTargetClassAnnotationCounter() {
atTargetClassAnnotationCounter++;
}
@Before("@annotation(org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests.TestAnnotation)")
public void incrementAtAnnotationMethodAnnotationCounter() {
atAnnotationMethodAnnotationCounter++;
}
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="false"/>
<bean id="counter"
class="org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests$Counter" />
<bean id="testBean" class="org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests$TestImpl" />
<bean id="testAnnotatedClassBean" class="org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests$AnnotatedClassTestImpl" />
<bean id="testAnnotatedMethodBean" class="org.springframework.aop.aspectj.ThisAndTargetSelectionOnlyPointcutsAtAspectJTests$AnnotatedMethodTestImpl" />
</beans>

View File

@@ -0,0 +1,120 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Ramnivas Laddad
* @author Chris Beams
*/
public final class ThisAndTargetSelectionOnlyPointcutsTests {
private TestInterface testBean;
private Counter thisAsClassCounter;
private Counter thisAsInterfaceCounter;
private Counter targetAsClassCounter;
private Counter targetAsInterfaceCounter;
private Counter thisAsClassAndTargetAsClassCounter;
private Counter thisAsInterfaceAndTargetAsInterfaceCounter;
private Counter thisAsInterfaceAndTargetAsClassCounter;
@Before
public void setUp() {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
testBean = (TestInterface) ctx.getBean("testBean");
thisAsClassCounter = (Counter) ctx.getBean("thisAsClassCounter");
thisAsInterfaceCounter = (Counter) ctx.getBean("thisAsInterfaceCounter");
targetAsClassCounter = (Counter) ctx.getBean("targetAsClassCounter");
targetAsInterfaceCounter = (Counter) ctx.getBean("targetAsInterfaceCounter");
thisAsClassAndTargetAsClassCounter = (Counter) ctx.getBean("thisAsClassAndTargetAsClassCounter");
thisAsInterfaceAndTargetAsInterfaceCounter = (Counter) ctx.getBean("thisAsInterfaceAndTargetAsInterfaceCounter");
thisAsInterfaceAndTargetAsClassCounter = (Counter) ctx.getBean("thisAsInterfaceAndTargetAsClassCounter");
thisAsClassCounter.reset();
thisAsInterfaceCounter.reset();
targetAsClassCounter.reset();
targetAsInterfaceCounter.reset();
thisAsClassAndTargetAsClassCounter.reset();
thisAsInterfaceAndTargetAsInterfaceCounter.reset();
thisAsInterfaceAndTargetAsClassCounter.reset();
}
@Test
public void testThisAsClassDoesNotMatch() {
testBean.doIt();
assertEquals(0, thisAsClassCounter.getCount());
}
@Test
public void testThisAsInterfaceMatch() {
testBean.doIt();
assertEquals(1, thisAsInterfaceCounter.getCount());
}
@Test
public void testTargetAsClassDoesMatch() {
testBean.doIt();
assertEquals(1, targetAsClassCounter.getCount());
}
@Test
public void testTargetAsInterfaceMatch() {
testBean.doIt();
assertEquals(1, targetAsInterfaceCounter.getCount());
}
@Test
public void testThisAsClassAndTargetAsClassCounterNotMatch() {
testBean.doIt();
assertEquals(0, thisAsClassAndTargetAsClassCounter.getCount());
}
@Test
public void testThisAsInterfaceAndTargetAsInterfaceCounterMatch() {
testBean.doIt();
assertEquals(1, thisAsInterfaceAndTargetAsInterfaceCounter.getCount());
}
@Test
public void testThisAsInterfaceAndTargetAsClassCounterMatch() {
testBean.doIt();
assertEquals(1, thisAsInterfaceAndTargetAsInterfaceCounter.getCount());
}
}
interface TestInterface {
public void doIt();
}
class TestImpl implements TestInterface {
public void doIt() {
}
}

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<aop:aspect ref="thisAsClassCounter">
<aop:before method="increment"
pointcut="this(org.springframework.aop.aspectj.TestImpl)" />
</aop:aspect>
<aop:aspect ref="thisAsInterfaceCounter">
<aop:before method="increment"
pointcut="this(org.springframework.aop.aspectj.TestInterface)" />
</aop:aspect>
<aop:aspect ref="targetAsClassCounter">
<aop:before method="increment"
pointcut="target(org.springframework.aop.aspectj.TestImpl)" />
</aop:aspect>
<aop:aspect ref="targetAsInterfaceCounter">
<aop:before method="increment"
pointcut="target(org.springframework.aop.aspectj.TestInterface)" />
</aop:aspect>
<aop:aspect ref="thisAsClassAndTargetAsClassCounter">
<aop:before method="increment"
pointcut="this(org.springframework.aop.aspectj.TestImpl) and target(org.springframework.aop.aspectj.TestImpl)" />
</aop:aspect>
<aop:aspect ref="thisAsInterfaceAndTargetAsInterfaceCounter">
<aop:before method="increment"
pointcut="this(org.springframework.aop.aspectj.TestInterface) and target(org.springframework.aop.aspectj.TestInterface)" />
</aop:aspect>
<aop:aspect ref="thisAsInterfaceAndTargetAsClassCounter">
<aop:before method="increment"
pointcut="this(org.springframework.aop.aspectj.TestInterface) and target(org.springframework.aop.aspectj.TestImpl)" />
</aop:aspect>
</aop:config>
<bean id="thisAsClassCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="thisAsInterfaceCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="targetAsClassCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="targetAsInterfaceCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="thisAsClassAndTargetAsClassCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="thisAsInterfaceAndTargetAsInterfaceCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="thisAsInterfaceAndTargetAsClassCounter" class="org.springframework.aop.aspectj.Counter" />
<bean id="testBean" class="org.springframework.aop.aspectj.TestImpl" />
</beans>

View File

@@ -0,0 +1,139 @@
package org.springframework.aop.aspectj;
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.aspectj.lang.JoinPoint;
/**
* Definitions of testing types for use in within this package.
* Wherever possible, test types should be defined local to the java
* file that makes use of them. In some cases however, a test type may
* need to be shared across tests. Such types reside here, with the
* intention of reducing the surface area of java files within this
* package. This allows developers to think about tests first, and deal
* with these second class testing artifacts on an as-needed basis.
*
* Types here should be defined as package-private top level classes in
* order to avoid needing to fully qualify, e.g.: _TestTypes$Foo.
*
* @author Chris Beams
*/
final class _TestTypes { }
/**
* Aspect used as part of before before advice binding tests and
* serves as base class for a number of more specialized test aspects.
*
* @author Adrian Colyer
* @author Chris Beams
*/
class AdviceBindingTestAspect {
protected AdviceBindingCollaborator collaborator = null;
public void setCollaborator(AdviceBindingCollaborator aCollaborator) {
this.collaborator = aCollaborator;
}
// "advice" methods
public void oneIntArg(int age) {
this.collaborator.oneIntArg(age);
}
public void oneObjectArg(Object bean) {
this.collaborator.oneObjectArg(bean);
}
public void oneIntAndOneObject(int x, Object o) {
this.collaborator.oneIntAndOneObject(x,o);
}
public void needsJoinPoint(JoinPoint tjp) {
this.collaborator.needsJoinPoint(tjp.getSignature().getName());
}
public void needsJoinPointStaticPart(JoinPoint.StaticPart tjpsp) {
this.collaborator.needsJoinPointStaticPart(tjpsp.getSignature().getName());
}
/**
* Collaborator interface that makes it easy to test this aspect is
* working as expected through mocking.
*/
public interface AdviceBindingCollaborator {
void oneIntArg(int x);
void oneObjectArg(Object o);
void oneIntAndOneObject(int x, Object o);
void needsJoinPoint(String s);
void needsJoinPointStaticPart(String s);
}
}
/**
* @author Ramnivas Laddad
*/
interface ICounter {
void increment();
void decrement();
int getCount();
void setCount(int counter);
void reset();
}
/**
* A simple counter for use in simple tests (for example, how many times an advice was executed)
*
* @author Ramnivas Laddad
*/
final class Counter implements ICounter {
private int count;
public Counter() {
}
public void increment() {
count++;
}
public void decrement() {
count--;
}
public int getCount() {
return count;
}
public void setCount(int counter) {
this.count = counter;
}
public void reset() {
this.count = 0;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test.mixin;
/**
* Simple implementation of Lockable interface for use in mixins.
*
* @author Rod Johnson
*/
public class DefaultLockable implements Lockable {
private boolean locked;
public void lock() {
this.locked = true;
}
public void unlock() {
this.locked = false;
}
public boolean locked() {
return this.locked;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test.mixin;
/**
* Simple interface to use for mixins
*
* @author Rod Johnson
*
*/
public interface Lockable {
void lock();
void unlock();
boolean locked();
}