提交 be53a806 编写于 作者: C Chris Beams

moved ApplicationContext-dependent .aop.* unit tests from .testsuite -> .context

in the process, identified and refactored two genuine integration tests (AopNamespaceHandlerScopeIntegrationTests, AdvisorAutoProxyCreatorIntegrationTests), which will remain in .testsuite due to broad-ranging dependencies
上级 2d37eb72
/**
*
*/
package example.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class TwoAdviceAspect {
private int totalCalls;
@Around("execution(* getAge())")
public int returnCallCount(ProceedingJoinPoint pjp) throws Exception {
return totalCalls;
}
@Before("execution(* setAge(int)) && args(newAge)")
public void countSet(int newAge) throws Exception {
++totalCalls;
}
}
\ No newline at end of file
......@@ -49,8 +49,9 @@ import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import example.aspects.PerTargetAspect;
import example.aspects.TwoAdviceAspect;
import test.aspect.PerTargetAspect;
import test.aspect.TwoAdviceAspect;
/**
* Abstract tests for AspectJAdvisorFactory.
......
......@@ -25,7 +25,8 @@ import org.springframework.aop.aspectj.AspectJExpressionPointcutTests;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.beans.TestBean;
import example.aspects.PerTargetAspect;
import test.aspect.PerTargetAspect;
/**
* @author Rod Johnson
......
......@@ -23,7 +23,8 @@ import org.junit.Test;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactoryTests.ExceptionAspect;
import example.aspects.PerTargetAspect;
import test.aspect.PerTargetAspect;
/**
* @since 2.0
......
......@@ -21,7 +21,8 @@ import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue;
import example.aspects.PerThisAspect;
import test.aspect.PerThisAspect;
/**
* @author Rob Harrop
......
/**
*
*/
package example.aspects;
package test.aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
......
......@@ -14,7 +14,7 @@
* limitations under the License.
*/
package example.aspects;
package test.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
......
/*
* 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 test.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class TwoAdviceAspect {
private int totalCalls;
@Around("execution(* getAge())")
public int returnCallCount(ProceedingJoinPoint pjp) throws Exception {
return totalCalls;
}
@Before("execution(* setAge(int)) && args(newAge)")
public void countSet(int newAge) throws Exception {
++totalCalls;
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-2.1.3.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-1.4.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jruby/com.springsource.org.jruby/1.1.0/com.springsource.org.jruby-1.1.0.jar" sourcepath="/IVY_CACHE/org.jruby/com.springsource.org.jruby/1.1.0/com.springsource.org.jruby-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.5.1/com.springsource.org.codehaus.groovy-1.5.1.jar" sourcepath="/IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.5.1/com.springsource.org.codehaus.groovy-sources-1.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.beanshell/com.springsource.bsh/2.0.0.b4/com.springsource.bsh-2.0.0.b4.jar"/>
......
......@@ -42,6 +42,7 @@
<dependency org="org.antlr" name="com.springsource.antlr" rev="2.7.6" conf="test->compile"/>
<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="compile->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.pool" rev="1.4.0" conf="test->compile"/>
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="1.6.2.RELEASE" conf="optional, aspectj->compile"/>
<dependency org="org.beanshell" name="com.springsource.bsh" rev="2.0.0.b4" conf="optional, beanshell->compile"/>
<dependency org="org.codehaus.groovy" name="com.springsource.org.codehaus.groovy" rev="1.5.1" conf="optional, groovy->compile"/>
......
......@@ -5,7 +5,7 @@
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
<bean class="example.aspects.PerTargetAspect"
<bean class="test.aspect.PerTargetAspect"
scope="prototype">
<property name="order" value="5"/>
</bean>
......
......@@ -5,7 +5,7 @@
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
<bean class="example.aspects.PerThisAspect" scope="prototype"/>
<bean class="test.aspect.PerThisAspect" scope="prototype"/>
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
<property name="name" value="adrian"/>
......
......@@ -5,7 +5,7 @@
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
<bean id="aspect" class="example.aspects.TwoAdviceAspect"/>
<bean id="aspect" class="test.aspect.TwoAdviceAspect"/>
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
<property name="name" value="adrian"/>
......
......@@ -5,7 +5,7 @@
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
<bean id="aspect" class="example.aspects.TwoAdviceAspect"
<bean id="aspect" class="test.aspect.TwoAdviceAspect"
scope="prototype"/>
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
......
......@@ -9,10 +9,6 @@
<aop:aspectj-autoproxy/>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.transaction.CallCountingTransactionManager"/>
<bean id="testAspect" class="org.springframework.aop.aspectj.autoproxy.AtAspectJAnnotationBindingTestAspect"/>
<bean id="testBean" class="org.springframework.aop.aspectj.autoproxy.AnnotatedTestBeanImpl"/>
......
......@@ -20,7 +20,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.transaction.annotation.Transactional;
/**
......@@ -71,7 +70,6 @@ interface AnnotatedTestBean {
* @author Adrian Colyer
* @since 2.0
*/
@Transactional
class AnnotatedTestBeanImpl implements AnnotatedTestBean {
@TestAnnotation("this value")
......
......@@ -16,7 +16,7 @@
package org.springframework.aop.aspectj.generic;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
......@@ -26,10 +26,11 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.Employee;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.beans.Employee;
/**
* Tests ensuring that after-returning advice for generic parameters bound to
* the advice and the return type follow AspectJ semantics.
......
......@@ -31,7 +31,10 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.advice.CountingBeforeAdvice;
/**
* Unit tests for aop namespace.
*
* @author Rob Harrop
* @author Chris Beams
*/
public class AopNamespaceHandlerTests {
......
......@@ -15,7 +15,7 @@
<constructor-arg ref="service"/>
</bean>
<bean id="nullInstance" class="org.springframework.beans.factory.xml.FactoryMethods" factory-method="nullInstance"/>
<bean id="nullInstance" class="test.beans.FactoryMethods" factory-method="nullInstance"/>
<bean id="serviceInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>
......
......@@ -19,6 +19,7 @@ package org.springframework.aop.framework;
import static org.junit.Assert.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.sql.SQLException;
......@@ -28,7 +29,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.transaction.TransactionRequiredException;
import junit.framework.TestCase;
......@@ -62,8 +62,6 @@ import org.springframework.beans.ITestBean;
import org.springframework.beans.Person;
import org.springframework.beans.SerializablePerson;
import org.springframework.beans.TestBean;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.util.SerializationTestUtils;
import org.springframework.util.StopWatch;
......@@ -241,9 +239,9 @@ public abstract class AbstractAopProxyTests {
p.echo(null);
assertEquals(0, cta.getCalls());
try {
p.echo(new ServletException());
p.echo(new IOException());
}
catch (ServletException ex) {
catch (IOException ex) {
}
assertEquals(1, cta.getCalls());
......@@ -276,9 +274,9 @@ public abstract class AbstractAopProxyTests {
p2.echo(null);
assertEquals(1, cta.getCalls());
try {
p2.echo(new ServletException());
p2.echo(new IOException());
}
catch (ServletException ex) {
catch (IOException ex) {
}
assertEquals(2, cta.getCalls());
......@@ -1424,15 +1422,15 @@ public abstract class AbstractAopProxyTests {
assertEquals(26, proxied.getAge());
assertEquals(4, cca.getCalls());
try {
proxied.exceptional(new CannotGetJdbcConnectionException("foo", (SQLException)null));
proxied.exceptional(new SpecializedUncheckedException("foo", (SQLException)null));
fail("Should have thrown CannotGetJdbcConnectionException");
}
catch (CannotGetJdbcConnectionException ex) {
catch (SpecializedUncheckedException ex) {
// expected
}
assertEquals(6, cca.getCalls());
}
@Test
public void testBeforeAdviceThrowsException() {
final RuntimeException rex = new RuntimeException();
......@@ -1933,12 +1931,12 @@ public abstract class AbstractAopProxyTests {
count(m);
}
public void afterThrowing(ServletException sex) throws Throwable {
count(ServletException.class.getName());
public void afterThrowing(IOException ex) throws Throwable {
count(IOException.class.getName());
}
public void afterThrowing(DataAccessException ex) throws Throwable {
count(DataAccessException.class.getName());
public void afterThrowing(UncheckedException ex) throws Throwable {
count(UncheckedException.class.getName());
}
}
......@@ -1947,16 +1945,31 @@ public abstract class AbstractAopProxyTests {
@SuppressWarnings("serial")
public static class CountingThrowsAdvice extends MethodCounter implements ThrowsAdvice {
public void afterThrowing(ServletException sex) throws Throwable {
count(ServletException.class.getName());
public void afterThrowing(IOException ex) throws Throwable {
count(IOException.class.getName());
}
public void afterThrowing(DataAccessException ex) throws Throwable {
count(DataAccessException.class.getName());
public void afterThrowing(UncheckedException ex) throws Throwable {
count(UncheckedException.class.getName());
}
}
@SuppressWarnings("serial")
static class UncheckedException extends RuntimeException {
}
@SuppressWarnings("serial")
static class SpecializedUncheckedException extends UncheckedException {
public SpecializedUncheckedException(String string, SQLException exception) {
}
}
static class MockTargetSource implements TargetSource {
......
......@@ -7,31 +7,31 @@
<beans>
<!-- Simple target -->
<bean id="test" class="common.beans.core.SideEffectBean">
<bean id="test" class="test.beans.SideEffectBean">
<property name="count"><value>10</value></property>
</bean>
<bean id="prototypeTarget" class="common.beans.core.SideEffectBean" scope="prototype">
<bean id="prototypeTarget" class="test.beans.SideEffectBean" scope="prototype">
<property name="count"><value>10</value></property>
</bean>
<bean id="debugInterceptor" class="test.interceptor.NopInterceptor"/>
<bean id="singleton" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames"><value>debugInterceptor,test</value></property>
<property name="interceptorNames"><value>debugInterceptor,test</value></property>
</bean>
<bean id="prototype" class="org.springframework.aop.framework.ProxyFactoryBean">
<bean id="prototype" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames"><value>debugInterceptor,prototypeTarget</value></property>
<property name="singleton"><value>false</value></property>
</bean>
<bean id="cglibPrototype"
class="org.springframework.aop.framework.ProxyFactoryBean">
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames"><value>debugInterceptor,prototypeTarget</value></property>
<property name="singleton"><value>false</value></property>
<!-- Force the use of CGLIB -->
<property name="proxyTargetClass"><value>true</value></property>
</bean>
</beans>
</beans>
......@@ -62,7 +62,7 @@ import test.mixin.Lockable;
import test.mixin.LockedException;
import test.util.TimeStamped;
import common.beans.core.SideEffectBean;
import test.beans.SideEffectBean;
/**
* @since 13.03.2003
......
/*
* 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.framework.autoproxy;
import static org.junit.Assert.*;
import java.io.IOException;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.autoproxy.target.AbstractBeanFactoryBasedTargetSourceCreator;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.AbstractBeanFactoryBasedTargetSource;
import org.springframework.aop.target.CommonsPoolTargetSource;
import org.springframework.aop.target.LazyInitTargetSource;
import org.springframework.aop.target.PrototypeTargetSource;
import org.springframework.aop.target.ThreadLocalTargetSource;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.advice.CountingBeforeAdvice;
import test.interceptor.NopInterceptor;
import test.mixin.Lockable;
/**
* Tests for auto proxy creation by advisor recognition.
*
* @see org.springframework.aop.framework.autoproxy.AdvisorAutoProxyCreatorIntegrationTests;
*
* @author Rod Johnson
* @author Dave Syer
* @author Chris Beams
*/
public final class AdvisorAutoProxyCreatorTests {
private static final Class<?> CLASS = AdvisorAutoProxyCreatorTests.class;
private static final String CLASSNAME = CLASS.getSimpleName();
private static final String DEFAULT_CONTEXT = CLASSNAME + "-context.xml";
private static final String COMMON_INTERCEPTORS_CONTEXT = CLASSNAME + "-common-interceptors.xml";
private static final String CUSTOM_TARGETSOURCE_CONTEXT = CLASSNAME + "-custom-targetsource.xml";
private static final String QUICK_TARGETSOURCE_CONTEXT = CLASSNAME + "-quick-targetsource.xml";
private static final String OPTIMIZED_CONTEXT = CLASSNAME + "-optimized.xml";
private static final String ADVISOR_APC_BEAN_NAME = "aapc";
private static final String TXMANAGER_BEAN_NAME = "txManager";
/**
* Return a bean factory with attributes and EnterpriseServices configured.
*/
protected BeanFactory getBeanFactory() throws IOException {
return new ClassPathXmlApplicationContext(DEFAULT_CONTEXT, CLASS);
}
/**
* Check that we can provide a common interceptor that will
* appear in the chain before "specific" interceptors,
* which are sourced from matching advisors
*/
@Test
public void testCommonInterceptorAndAdvisor() throws Exception {
BeanFactory bf = new ClassPathXmlApplicationContext(COMMON_INTERCEPTORS_CONTEXT, CLASS);
ITestBean test1 = (ITestBean) bf.getBean("test1");
assertTrue(AopUtils.isAopProxy(test1));
Lockable lockable1 = (Lockable) test1;
NopInterceptor nop = (NopInterceptor) bf.getBean("nopInterceptor");
assertEquals(0, nop.getCount());
ITestBean test2 = (ITestBean) bf.getBean("test2");
Lockable lockable2 = (Lockable) test2;
// Locking should be independent; nop is shared
assertFalse(lockable1.locked());
assertFalse(lockable2.locked());
// equals 2 calls on shared nop, because it's first
// and sees calls against the Lockable interface introduced
// by the specific advisor
assertEquals(2, nop.getCount());
lockable1.lock();
assertTrue(lockable1.locked());
assertFalse(lockable2.locked());
assertEquals(5, nop.getCount());
}
/**
* We have custom TargetSourceCreators but there's no match, and
* hence no proxying, for this bean
*/
@Test
public void testCustomTargetSourceNoMatch() throws Exception {
BeanFactory bf = new ClassPathXmlApplicationContext(CUSTOM_TARGETSOURCE_CONTEXT, CLASS);
ITestBean test = (ITestBean) bf.getBean("test");
assertFalse(AopUtils.isAopProxy(test));
assertEquals("Rod", test.getName());
assertEquals("Kerry", test.getSpouse().getName());
}
@Test
public void testCustomPrototypeTargetSource() throws Exception {
CountingTestBean.count = 0;
BeanFactory bf = new ClassPathXmlApplicationContext(CUSTOM_TARGETSOURCE_CONTEXT, CLASS);
ITestBean test = (ITestBean) bf.getBean("prototypeTest");
assertTrue(AopUtils.isAopProxy(test));
Advised advised = (Advised) test;
assertTrue(advised.getTargetSource() instanceof PrototypeTargetSource);
assertEquals("Rod", test.getName());
// Check that references survived prototype creation
assertEquals("Kerry", test.getSpouse().getName());
assertEquals("Only 2 CountingTestBeans instantiated", 2, CountingTestBean.count);
CountingTestBean.count = 0;
}
@Test
public void testLazyInitTargetSource() throws Exception {
CountingTestBean.count = 0;
BeanFactory bf = new ClassPathXmlApplicationContext(CUSTOM_TARGETSOURCE_CONTEXT, CLASS);
ITestBean test = (ITestBean) bf.getBean("lazyInitTest");
assertTrue(AopUtils.isAopProxy(test));
Advised advised = (Advised) test;
assertTrue(advised.getTargetSource() instanceof LazyInitTargetSource);
assertEquals("No CountingTestBean instantiated yet", 0, CountingTestBean.count);
assertEquals("Rod", test.getName());
assertEquals("Kerry", test.getSpouse().getName());
assertEquals("Only 1 CountingTestBean instantiated", 1, CountingTestBean.count);
CountingTestBean.count = 0;
}
@Test
public void testQuickTargetSourceCreator() throws Exception {
ClassPathXmlApplicationContext bf =
new ClassPathXmlApplicationContext(QUICK_TARGETSOURCE_CONTEXT, CLASS);
ITestBean test = (ITestBean) bf.getBean("test");
assertFalse(AopUtils.isAopProxy(test));
assertEquals("Rod", test.getName());
// Check that references survived pooling
assertEquals("Kerry", test.getSpouse().getName());
// Now test the pooled one
test = (ITestBean) bf.getBean(":test");
assertTrue(AopUtils.isAopProxy(test));
Advised advised = (Advised) test;
assertTrue(advised.getTargetSource() instanceof CommonsPoolTargetSource);
assertEquals("Rod", test.getName());
// Check that references survived pooling
assertEquals("Kerry", test.getSpouse().getName());
// Now test the ThreadLocal one
test = (ITestBean) bf.getBean("%test");
assertTrue(AopUtils.isAopProxy(test));
advised = (Advised) test;
assertTrue(advised.getTargetSource() instanceof ThreadLocalTargetSource);
assertEquals("Rod", test.getName());
// Check that references survived pooling
assertEquals("Kerry", test.getSpouse().getName());
// Now test the Prototype TargetSource
test = (ITestBean) bf.getBean("!test");
assertTrue(AopUtils.isAopProxy(test));
advised = (Advised) test;
assertTrue(advised.getTargetSource() instanceof PrototypeTargetSource);
assertEquals("Rod", test.getName());
// Check that references survived pooling
assertEquals("Kerry", test.getSpouse().getName());
ITestBean test2 = (ITestBean) bf.getBean("!test");
assertFalse("Prototypes cannot be the same object", test == test2);
assertEquals("Rod", test2.getName());
assertEquals("Kerry", test2.getSpouse().getName());
bf.close();
}
@Test
public void testWithOptimizedProxy() throws Exception {
BeanFactory beanFactory = new ClassPathXmlApplicationContext(OPTIMIZED_CONTEXT, CLASS);
ITestBean testBean = (ITestBean) beanFactory.getBean("optimizedTestBean");
assertTrue(AopUtils.isAopProxy(testBean));
CountingBeforeAdvice beforeAdvice = (CountingBeforeAdvice) beanFactory.getBean("countingAdvice");
testBean.setAge(23);
testBean.getAge();
assertEquals("Incorrect number of calls to proxy", 2, beforeAdvice.getCalls());
}
}
class CountingTestBean extends TestBean {
public static int count = 0;
public CountingTestBean() {
count++;
}
}
class SelectivePrototypeTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {
protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(
Class<?> beanClass, String beanName) {
if (!beanName.startsWith("prototype")) {
return null;
}
return new PrototypeTargetSource();
}
}
......@@ -16,9 +16,12 @@
package org.springframework.aop.framework.autoproxy;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import org.junit.Test;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.TestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
......@@ -40,3 +43,20 @@ public final class BeanNameAutoProxyCreatorInitTests {
}
}
class NullChecker implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
check(args);
}
private void check(Object[] args) {
for (int i = 0; i < args.length; i++) {
if (args[i] == null) {
throw new IllegalArgumentException("Null argument at position " + i);
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册