Rename modules {org.springframework.*=>spring-*}
This renaming more intuitively expresses the relationship between
subprojects and the JAR artifacts they produce.
Tracking history across these renames is possible, but it requires
use of the --follow flag to `git log`, for example
$ git log spring-aop/src/main/java/org/springframework/aop/Advisor.java
will show history up until the renaming event, where
$ git log --follow spring-aop/src/main/java/org/springframework/aop/Advisor.java
will show history for all changes to the file, before and after the
renaming.
See http://chrisbeams.com/git-diff-across-renamed-directories
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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 example.profilescan;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Profile(DevComponent.PROFILE_NAME)
|
||||
@Component
|
||||
public @interface DevComponent {
|
||||
|
||||
public static final String PROFILE_NAME = "dev";
|
||||
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package example.profilescan;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Profile(ProfileAnnotatedComponent.PROFILE_NAME)
|
||||
@Component(ProfileAnnotatedComponent.BEAN_NAME)
|
||||
public class ProfileAnnotatedComponent {
|
||||
|
||||
public static final String BEAN_NAME = "profileAnnotatedComponent";
|
||||
public static final String PROFILE_NAME = "test";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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 example.profilescan;
|
||||
|
||||
|
||||
@DevComponent(ProfileMetaAnnotatedComponent.BEAN_NAME)
|
||||
public class ProfileMetaAnnotatedComponent {
|
||||
|
||||
public static final String BEAN_NAME = "profileMetaAnnotatedComponent";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Lazy
|
||||
public class AutowiredQualifierFooService implements FooService {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("testing")
|
||||
private FooDao fooDao;
|
||||
|
||||
private boolean initCalled = false;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
if (this.initCalled) {
|
||||
throw new IllegalStateException("Init already called");
|
||||
}
|
||||
this.initCalled = true;
|
||||
}
|
||||
|
||||
public String foo(int id) {
|
||||
return this.fooDao.findFoo(id);
|
||||
}
|
||||
|
||||
public Future<String> asyncFoo(int id) {
|
||||
return new AsyncResult<String>(this.fooDao.findFoo(id));
|
||||
}
|
||||
|
||||
public boolean isInitCalled() {
|
||||
return this.initCalled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface CustomComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Service
|
||||
@Scope("prototype")
|
||||
public @interface CustomStereotype {
|
||||
|
||||
String value() default "thoreau";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@CustomStereotype
|
||||
public class DefaultNamedComponent {
|
||||
|
||||
}
|
||||
26
spring-context/src/test/java/example/scannable/FooDao.java
Normal file
26
spring-context/src/test/java/example/scannable/FooDao.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public interface FooDao {
|
||||
|
||||
String findFoo(int id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public interface FooService {
|
||||
|
||||
String foo(int id);
|
||||
|
||||
@Async
|
||||
Future<String> asyncFoo(int id);
|
||||
|
||||
boolean isInitCalled();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Service @Lazy @DependsOn("myNamedComponent")
|
||||
public class FooServiceImpl implements FooService {
|
||||
|
||||
@Autowired private FooDao fooDao;
|
||||
|
||||
@Autowired public BeanFactory beanFactory;
|
||||
|
||||
@Autowired public List<ListableBeanFactory> listableBeanFactory;
|
||||
|
||||
@Autowired public ResourceLoader resourceLoader;
|
||||
|
||||
@Autowired public ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
@Autowired public ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired public MessageSource messageSource;
|
||||
|
||||
@Autowired public ApplicationContext context;
|
||||
|
||||
@Autowired public ConfigurableApplicationContext[] configurableContext;
|
||||
|
||||
@Autowired public AbstractApplicationContext genericContext;
|
||||
|
||||
private boolean initCalled = false;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
if (this.initCalled) {
|
||||
throw new IllegalStateException("Init already called");
|
||||
}
|
||||
this.initCalled = true;
|
||||
}
|
||||
|
||||
public String foo(int id) {
|
||||
return this.fooDao.findFoo(id);
|
||||
}
|
||||
|
||||
public Future<String> asyncFoo(int id) {
|
||||
System.out.println(Thread.currentThread().getName());
|
||||
Assert.state(ServiceInvocationCounter.getThreadLocalCount() != null, "Thread-local counter not exposed");
|
||||
return new AsyncResult<String>(this.fooDao.findFoo(id));
|
||||
}
|
||||
|
||||
public boolean isInitCalled() {
|
||||
return this.initCalled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@CustomComponent
|
||||
public class MessageBean {
|
||||
|
||||
private String message;
|
||||
|
||||
public MessageBean() {
|
||||
this.message = "DEFAULT MESSAGE";
|
||||
}
|
||||
|
||||
public MessageBean(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@Component("myNamedComponent") @Lazy
|
||||
public class NamedComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Repository("myNamedDao")
|
||||
public class NamedStubDao {
|
||||
|
||||
public String find(int id) {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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 example.scannable;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Scope("myScope")
|
||||
public class ScopedProxyTestBean implements FooService {
|
||||
|
||||
public String foo(int id) {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
public Future<String> asyncFoo(int id) {
|
||||
return new AsyncResult<String>("bar");
|
||||
}
|
||||
|
||||
public boolean isInitCalled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@Component
|
||||
@Aspect
|
||||
public class ServiceInvocationCounter {
|
||||
|
||||
private int useCount;
|
||||
|
||||
private static final ThreadLocal<Integer> threadLocalCount = new ThreadLocal<Integer>();
|
||||
|
||||
|
||||
@Pointcut("execution(* example.scannable.FooService+.*(..))")
|
||||
public void serviceExecution() {}
|
||||
|
||||
@Before("serviceExecution()")
|
||||
public void countUse() {
|
||||
this.useCount++;
|
||||
this.threadLocalCount.set(this.useCount);
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.useCount;
|
||||
}
|
||||
|
||||
public static Integer getThreadLocalCount() {
|
||||
return threadLocalCount.get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 example.scannable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@Repository
|
||||
@Qualifier("testing")
|
||||
public class StubFooDao implements FooDao {
|
||||
|
||||
public String findFoo(int id) {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
25
spring-context/src/test/java/example/scannable/_package.java
Normal file
25
spring-context/src/test/java/example/scannable/_package.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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 example.scannable;
|
||||
|
||||
|
||||
/**
|
||||
* Marker class for example.scannable package.
|
||||
*
|
||||
* @see org.springframework.context.annotation.ComponentScan#basePackageClasses()
|
||||
*/
|
||||
public class _package { }
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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 example.scannable_scoped;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@MyScope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
public class CustomScopeAnnotationBean {
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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 example.scannable_scoped;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
|
||||
public @interface MyScope {
|
||||
String value() default BeanDefinition.SCOPE_SINGLETON;
|
||||
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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 @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++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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(&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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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) {}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 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;
|
||||
}
|
||||
}
|
||||
@@ -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:config>
|
||||
<aop:aspect id="annotationBindingAspect" ref="testAspect">
|
||||
<aop:around pointcut="@annotation(testAnnotation)" method="doWithAnnotation"/>
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
|
||||
<bean id="testAspect" class="org.springframework.aop.aspectj.autoproxy.AnnotationBindingTestAspect"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.aop.aspectj.autoproxy.AnnotatedTestBeanImpl"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AnnotationBindingTests {
|
||||
|
||||
private AnnotatedTestBean testBean;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
testBean = (AnnotatedTestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationBindingInAroundAdvice() {
|
||||
assertEquals("this value", testBean.doThis());
|
||||
assertEquals("that value", testBean.doThat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingWithoutAnnotationPresent() {
|
||||
assertEquals("doTheOther", testBean.doTheOther());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:advisor advice-ref="testInterceptor" pointcut-ref="myPointcut"/>
|
||||
</aop:config>
|
||||
|
||||
<bean id="testInterceptor" class="org.springframework.aop.aspectj.autoproxy.TestMethodInterceptor"/>
|
||||
|
||||
<bean id="myPointcut" class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut" factory-method="forMethodAnnotation">
|
||||
<constructor-arg value="org.springframework.aop.aspectj.autoproxy.TestAnnotation"/>
|
||||
</bean>
|
||||
|
||||
<bean id="testAspect" class="org.springframework.aop.aspectj.autoproxy.AnnotationBindingTestAspect"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.aop.aspectj.autoproxy.AnnotatedTestBeanImpl"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AnnotationPointcutTests {
|
||||
|
||||
private AnnotatedTestBean testBean;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
testBean = (AnnotatedTestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationBindingInAroundAdvice() {
|
||||
assertEquals("this value", testBean.doThis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingWithoutAnnotationPresent() {
|
||||
assertEquals("doTheOther", testBean.doTheOther());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TestMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||
return "this value";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ref="interfaceExtendingAspect">
|
||||
<aop:pointcut id="anyOperation"
|
||||
expression="execution(* *(..))"/>
|
||||
<aop:around pointcut-ref="anyOperation" method="increment"/>
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
|
||||
<bean id="testBean" class="org.springframework.beans.TestBean" />
|
||||
|
||||
<bean id="interfaceExtendingAspect"
|
||||
class="org.springframework.aop.aspectj.autoproxy.InterfaceExtendingAspect"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* Test for ensuring the aspects aren't advised. See SPR-3893 for more details.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AspectImplementingInterfaceTests {
|
||||
|
||||
@Test
|
||||
public void testProxyCreation() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
ITestBean testBean = (ITestBean) ctx.getBean("testBean");
|
||||
AnInterface interfaceExtendingAspect = (AnInterface) ctx.getBean("interfaceExtendingAspect");
|
||||
|
||||
assertTrue(testBean instanceof Advised);
|
||||
assertFalse(interfaceExtendingAspect instanceof Advised);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface AnInterface {
|
||||
public void interfaceMethod();
|
||||
}
|
||||
|
||||
|
||||
class InterfaceExtendingAspect implements AnInterface {
|
||||
public void increment(ProceedingJoinPoint pjp) throws Throwable {
|
||||
pjp.proceed();
|
||||
}
|
||||
|
||||
public void interfaceMethod() {
|
||||
}
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
|
||||
<property name="customTargetSourceCreators">
|
||||
<bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue">
|
||||
<property name="multiple" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrianParent" abstract="true">
|
||||
<property name="name" value="adrian"/>
|
||||
</bean>
|
||||
|
||||
<!-- parent="adrianParent" -->
|
||||
<bean id="adrian" class="org.springframework.aop.aspectj.autoproxy.LazyTestBean" lazy-init="true">
|
||||
<property name="age" value="34"/>
|
||||
<property name="name" value="adrian"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AspectJAutoProxyCreatorAndLazyInitTargetSourceTests {
|
||||
|
||||
@Test
|
||||
public void testAdrian() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
ITestBean adrian = (ITestBean) ctx.getBean("adrian");
|
||||
assertEquals(0, LazyTestBean.instantiations);
|
||||
assertNotNull(adrian);
|
||||
adrian.getAge();
|
||||
assertEquals(68, adrian.getAge());
|
||||
assertEquals(1, LazyTestBean.instantiations);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class LazyTestBean extends TestBean {
|
||||
|
||||
public static int instantiations;
|
||||
|
||||
public LazyTestBean() {
|
||||
++instantiations;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
|
||||
-->
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue">
|
||||
<property name="multiple" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.DummyAspect"/>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.DummyAspectWithParameter"/>
|
||||
|
||||
<bean id="adrianParent" abstract="true">
|
||||
<property name="name" value="adrian"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" parent="adrianParent">
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian2Parent" class="org.springframework.beans.TestBean" abstract="true">
|
||||
<property name="name" value="adrian"/>
|
||||
</bean>
|
||||
|
||||
<bean id="factoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
<property name="targetObject" ref="adrian"/>
|
||||
<property name="targetMethod" value="toString"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean id="aspect" class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue">
|
||||
<property name="multiple" value="3"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="Adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian2" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="Adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
<bean id="i21" class="org.springframework.beans.NestedTestBean" scope="prototype">
|
||||
<property name="company" value="i21"/>
|
||||
</bean>
|
||||
|
||||
<bean id="advisor" class="org.springframework.aop.aspectj.autoproxy.TestBeanAdvisor"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
|
||||
default-lazy-init="true">
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue">
|
||||
<property name="multiple" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="factoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
<property name="targetObject" ref="adrian"/>
|
||||
<property name="targetMethod" value="toString"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrianParent" abstract="true">
|
||||
<property name="name" value="adrian"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" parent="adrianParent">
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian2Parent" class="org.springframework.aop.aspectj.autoproxy.DummyFactoryBean" abstract="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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-3.0.xsd">
|
||||
|
||||
|
||||
<!--
|
||||
<bean
|
||||
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
|
||||
-->
|
||||
|
||||
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
|
||||
-->
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue">
|
||||
<property name="multiple" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.IncreaseReturnValue"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean class="test.aspect.PerTargetAspect"
|
||||
scope="prototype">
|
||||
<property name="order" value="5"/>
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
<bean id="juergen" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="juergen"/>
|
||||
<property name="age" value="30"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean class="test.aspect.PerThisAspect" scope="prototype"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<aop:aspectj-autoproxy proxy-target-class="true"/>
|
||||
|
||||
<bean id="retryAspect" class="org.springframework.aop.aspectj.autoproxy.RetryAspect"/>
|
||||
|
||||
<bean id="unreliableBean" class="org.springframework.aop.aspectj.autoproxy.UnreliableBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean id="aspect" class="test.aspect.TwoAdviceAspect"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean id="aspect" class="test.aspect.TwoAdviceAspect"
|
||||
scope="prototype"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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>
|
||||
<aop:include name="aspectOne"/>
|
||||
</aop:aspectj-autoproxy>
|
||||
|
||||
<bean id="aspectOne" class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue" >
|
||||
<property name="multiple" value="2" />
|
||||
</bean>
|
||||
|
||||
<bean id="aspectTwo"
|
||||
class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue" >
|
||||
<property name="multiple" value="2" />
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="adrian" />
|
||||
<property name="age" value="34" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
|
||||
|
||||
<bean id="aspect" class="org.springframework.aop.aspectj.autoproxy.AdviceUsingThisJoinPoint"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.autoproxy;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
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.aspectj.lang.annotation.Pointcut;
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
|
||||
import org.springframework.aop.aspectj.annotation.AspectMetadata;
|
||||
import org.springframework.aop.config.AopConfigUtils;
|
||||
import org.springframework.aop.framework.ProxyConfig;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
|
||||
import org.springframework.beans.INestedTestBean;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.beans.NestedTestBean;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
/**
|
||||
* Integration tests for AspectJ auto-proxying. Includes mixing with Spring AOP Advisors
|
||||
* to demonstrate that existing autoproxying contract is honoured.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public final class AspectJAutoProxyCreatorTests {
|
||||
|
||||
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
|
||||
|
||||
private static void assertStopWatchTimeLimit(final StopWatch sw, final long maxTimeMillis) {
|
||||
final long totalTimeMillis = sw.getTotalTimeMillis();
|
||||
assertTrue("'" + sw.getLastTaskName() + "' took too long: expected less than<" + maxTimeMillis
|
||||
+ "> ms, actual<" + totalTimeMillis + "> ms.", totalTimeMillis < maxTimeMillis);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAreApplied() {
|
||||
ClassPathXmlApplicationContext bf = newContext("aspects.xml");
|
||||
ITestBean tb = (ITestBean) bf.getBean("adrian");
|
||||
assertEquals(68, tb.getAge());
|
||||
MethodInvokingFactoryBean factoryBean = (MethodInvokingFactoryBean) bf.getBean("&factoryBean");
|
||||
assertTrue(AopUtils.isAopProxy(factoryBean.getTargetObject()));
|
||||
assertEquals(68, ((ITestBean) factoryBean.getTargetObject()).getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAspectsWithParameterApplied() {
|
||||
ClassPathXmlApplicationContext bf = newContext("aspects.xml");
|
||||
ITestBean tb = (ITestBean) bf.getBean("adrian");
|
||||
tb.setAge(10);
|
||||
assertEquals(20, tb.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAreAppliedInDefinedOrder() {
|
||||
ClassPathXmlApplicationContext bf = newContext("aspectsWithOrdering.xml");
|
||||
ITestBean tb = (ITestBean) bf.getBean("adrian");
|
||||
assertEquals(71, tb.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAndAdvisorAreApplied() {
|
||||
ClassPathXmlApplicationContext ac = newContext("aspectsPlusAdvisor.xml");
|
||||
ITestBean shouldBeWeaved = (ITestBean) ac.getBean("adrian");
|
||||
doTestAspectsAndAdvisorAreApplied(ac, shouldBeWeaved);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAndAdvisorAppliedToPrototypeIsFastEnough() {
|
||||
if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
|
||||
// Skip this test: Trace logging blows the time limit.
|
||||
return;
|
||||
}
|
||||
ClassPathXmlApplicationContext ac = newContext("aspectsPlusAdvisor.xml");
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("Prototype Creation");
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ITestBean shouldBeWeaved = (ITestBean) ac.getBean("adrian2");
|
||||
if (i < 10) {
|
||||
doTestAspectsAndAdvisorAreApplied(ac, shouldBeWeaved);
|
||||
}
|
||||
}
|
||||
sw.stop();
|
||||
|
||||
// What's a reasonable expectation for _any_ server or developer machine load?
|
||||
// 9 seconds?
|
||||
assertStopWatchTimeLimit(sw, 9000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAndAdvisorNotAppliedToPrototypeIsFastEnough() {
|
||||
if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
|
||||
// Skip this test: Trace logging blows the time limit.
|
||||
return;
|
||||
}
|
||||
ClassPathXmlApplicationContext ac = newContext("aspectsPlusAdvisor.xml");
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("Prototype Creation");
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
INestedTestBean shouldNotBeWeaved = (INestedTestBean) ac.getBean("i21");
|
||||
if (i < 10) {
|
||||
assertFalse(AopUtils.isAopProxy(shouldNotBeWeaved));
|
||||
}
|
||||
}
|
||||
sw.stop();
|
||||
|
||||
// What's a reasonable expectation for _any_ server or developer machine load?
|
||||
// 3 seconds?
|
||||
assertStopWatchTimeLimit(sw, 3000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAndAdvisorNotAppliedToManySingletonsIsFastEnough() {
|
||||
if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
|
||||
// Skip this test: Trace logging blows the time limit.
|
||||
return;
|
||||
}
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
new XmlBeanDefinitionReader(ac).loadBeanDefinitions(new ClassPathResource(qName("aspectsPlusAdvisor.xml"),
|
||||
getClass()));
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ac.registerBeanDefinition("singleton" + i, new RootBeanDefinition(NestedTestBean.class));
|
||||
}
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start("Singleton Creation");
|
||||
ac.refresh();
|
||||
sw.stop();
|
||||
|
||||
// What's a reasonable expectation for _any_ server or developer machine load?
|
||||
// 8 seconds?
|
||||
assertStopWatchTimeLimit(sw, 8000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectsAndAdvisorAreAppliedEvenIfComingFromParentFactory() {
|
||||
ClassPathXmlApplicationContext ac = newContext("aspectsPlusAdvisor.xml");
|
||||
GenericApplicationContext childAc = new GenericApplicationContext(ac);
|
||||
// Create a child factory with a bean that should be woven
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
bd.getPropertyValues().addPropertyValue(new PropertyValue("name", "Adrian"))
|
||||
.addPropertyValue(new PropertyValue("age", new Integer(34)));
|
||||
childAc.registerBeanDefinition("adrian2", bd);
|
||||
// Register the advisor auto proxy creator with subclass
|
||||
childAc.registerBeanDefinition(AnnotationAwareAspectJAutoProxyCreator.class.getName(), new RootBeanDefinition(
|
||||
AnnotationAwareAspectJAutoProxyCreator.class));
|
||||
childAc.refresh();
|
||||
|
||||
ITestBean beanFromChildContextThatShouldBeWeaved = (ITestBean) childAc.getBean("adrian2");
|
||||
//testAspectsAndAdvisorAreApplied(childAc, (ITestBean) ac.getBean("adrian"));
|
||||
doTestAspectsAndAdvisorAreApplied(childAc, beanFromChildContextThatShouldBeWeaved);
|
||||
}
|
||||
|
||||
protected void doTestAspectsAndAdvisorAreApplied(ApplicationContext ac, ITestBean shouldBeWeaved) {
|
||||
TestBeanAdvisor tba = (TestBeanAdvisor) ac.getBean("advisor");
|
||||
|
||||
MultiplyReturnValue mrv = (MultiplyReturnValue) ac.getBean("aspect");
|
||||
assertEquals(3, mrv.getMultiple());
|
||||
|
||||
tba.count = 0;
|
||||
mrv.invocations = 0;
|
||||
|
||||
assertTrue("Autoproxying must apply from @AspectJ aspect", AopUtils.isAopProxy(shouldBeWeaved));
|
||||
assertEquals("Adrian", shouldBeWeaved.getName());
|
||||
assertEquals(0, mrv.invocations);
|
||||
assertEquals(34 * mrv.getMultiple(), shouldBeWeaved.getAge());
|
||||
assertEquals("Spring advisor must be invoked", 2, tba.count);
|
||||
assertEquals("Must be able to hold state in aspect", 1, mrv.invocations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerThisAspect() {
|
||||
ClassPathXmlApplicationContext bf = newContext("perthis.xml");
|
||||
|
||||
ITestBean adrian1 = (ITestBean) bf.getBean("adrian");
|
||||
assertTrue(AopUtils.isAopProxy(adrian1));
|
||||
|
||||
assertEquals(0, adrian1.getAge());
|
||||
assertEquals(1, adrian1.getAge());
|
||||
|
||||
ITestBean adrian2 = (ITestBean) bf.getBean("adrian");
|
||||
assertNotSame(adrian1, adrian2);
|
||||
assertTrue(AopUtils.isAopProxy(adrian1));
|
||||
assertEquals(0, adrian2.getAge());
|
||||
assertEquals(1, adrian2.getAge());
|
||||
assertEquals(2, adrian2.getAge());
|
||||
assertEquals(3, adrian2.getAge());
|
||||
assertEquals(2, adrian1.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerTargetAspect() throws SecurityException, NoSuchMethodException {
|
||||
ClassPathXmlApplicationContext bf = newContext("pertarget.xml");
|
||||
|
||||
ITestBean adrian1 = (ITestBean) bf.getBean("adrian");
|
||||
assertTrue(AopUtils.isAopProxy(adrian1));
|
||||
|
||||
// Does not trigger advice or count
|
||||
int explicitlySetAge = 25;
|
||||
adrian1.setAge(explicitlySetAge);
|
||||
|
||||
assertEquals("Setter does not initiate advice", explicitlySetAge, adrian1.getAge());
|
||||
// Fire aspect
|
||||
|
||||
AspectMetadata am = new AspectMetadata(PerTargetAspect.class, "someBean");
|
||||
assertTrue(am.getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null));
|
||||
|
||||
adrian1.getSpouse();
|
||||
|
||||
assertEquals("Advice has now been instantiated", 0, adrian1.getAge());
|
||||
adrian1.setAge(11);
|
||||
assertEquals("Any int setter increments", 2, adrian1.getAge());
|
||||
adrian1.setName("Adrian");
|
||||
//assertEquals("Any other setter does not increment", 2, adrian1.getAge());
|
||||
|
||||
ITestBean adrian2 = (ITestBean) bf.getBean("adrian");
|
||||
assertNotSame(adrian1, adrian2);
|
||||
assertTrue(AopUtils.isAopProxy(adrian1));
|
||||
assertEquals(34, adrian2.getAge());
|
||||
adrian2.getSpouse();
|
||||
assertEquals("Aspect now fired", 0, adrian2.getAge());
|
||||
assertEquals(1, adrian2.getAge());
|
||||
assertEquals(2, adrian2.getAge());
|
||||
assertEquals(3, adrian1.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoAdviceAspectSingleton() {
|
||||
doTestTwoAdviceAspectWith("twoAdviceAspect.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoAdviceAspectPrototype() {
|
||||
doTestTwoAdviceAspectWith("twoAdviceAspectPrototype.xml");
|
||||
}
|
||||
|
||||
private void doTestTwoAdviceAspectWith(String location) {
|
||||
ClassPathXmlApplicationContext bf = newContext(location);
|
||||
|
||||
boolean aspectSingleton = bf.isSingleton("aspect");
|
||||
ITestBean adrian1 = (ITestBean) bf.getBean("adrian");
|
||||
testPrototype(adrian1, 0);
|
||||
ITestBean adrian2 = (ITestBean) bf.getBean("adrian");
|
||||
assertNotSame(adrian1, adrian2);
|
||||
testPrototype(adrian2, aspectSingleton ? 2 : 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdviceUsingJoinPoint() {
|
||||
ClassPathXmlApplicationContext bf = newContext("usesJoinPointAspect.xml");
|
||||
|
||||
ITestBean adrian1 = (ITestBean) bf.getBean("adrian");
|
||||
adrian1.getAge();
|
||||
AdviceUsingThisJoinPoint aspectInstance = (AdviceUsingThisJoinPoint) bf.getBean("aspect");
|
||||
//(AdviceUsingThisJoinPoint) Aspects.aspectOf(AdviceUsingThisJoinPoint.class);
|
||||
//assertEquals("method-execution(int TestBean.getAge())",aspectInstance.getLastMethodEntered());
|
||||
assertTrue(aspectInstance.getLastMethodEntered().indexOf("TestBean.getAge())") != 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncludeMechanism() {
|
||||
ClassPathXmlApplicationContext bf = newContext("usesInclude.xml");
|
||||
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
assertEquals(68, adrian.getAge());
|
||||
}
|
||||
|
||||
private void testPrototype(ITestBean adrian1, int start) {
|
||||
assertTrue(AopUtils.isAopProxy(adrian1));
|
||||
//TwoAdviceAspect twoAdviceAspect = (TwoAdviceAspect) bf.getBean(TwoAdviceAspect.class.getName());
|
||||
adrian1.setName("");
|
||||
assertEquals(start++, adrian1.getAge());
|
||||
int newAge = 32;
|
||||
adrian1.setAge(newAge);
|
||||
assertEquals(start++, adrian1.getAge());
|
||||
adrian1.setAge(0);
|
||||
assertEquals(start++, adrian1.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceProxyTargetClass() {
|
||||
ClassPathXmlApplicationContext bf = newContext("aspectsWithCGLIB.xml");
|
||||
|
||||
ProxyConfig pc = (ProxyConfig) bf.getBean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
assertTrue("should be proxying classes", pc.isProxyTargetClass());
|
||||
assertTrue("should expose proxy", pc.isExposeProxy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAbstractFactoryBeanAreApplied() {
|
||||
ClassPathXmlApplicationContext bf = newContext("aspectsWithAbstractBean.xml");
|
||||
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
assertEquals(68, adrian.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryAspect() throws Exception {
|
||||
ClassPathXmlApplicationContext bf = newContext("retryAspect.xml");
|
||||
UnreliableBean bean = (UnreliableBean) bf.getBean("unreliableBean");
|
||||
RetryAspect aspect = (RetryAspect) bf.getBean("retryAspect");
|
||||
int attempts = bean.unreliable();
|
||||
assertEquals(2, attempts);
|
||||
assertEquals(2, aspect.getBeginCalls());
|
||||
assertEquals(1, aspect.getRollbackCalls());
|
||||
assertEquals(1, aspect.getCommitCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ClassPathXmlApplicationContext} for the file ending in <var>fileSuffix</var>.
|
||||
*/
|
||||
private ClassPathXmlApplicationContext newContext(String fileSuffix) {
|
||||
return new ClassPathXmlApplicationContext(qName(fileSuffix), getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relatively qualified name for <var>fileSuffix</var>.
|
||||
* e.g. for a fileSuffix='foo.xml', this method will return
|
||||
* 'AspectJAutoProxyCreatorTests-foo.xml'
|
||||
*/
|
||||
private String qName(String fileSuffix) {
|
||||
return format("%s-%s", getClass().getSimpleName(), fileSuffix);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect("pertarget(execution(* *.getSpouse()))")
|
||||
class PerTargetAspect implements Ordered {
|
||||
|
||||
public int count;
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
@Around("execution(int *.getAge())")
|
||||
public int returnCountAsAge() {
|
||||
return count++;
|
||||
}
|
||||
|
||||
@Before("execution(void *.set*(int))")
|
||||
public void countSetter() {
|
||||
++count;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
@Aspect
|
||||
class AdviceUsingThisJoinPoint {
|
||||
|
||||
private String lastEntry = "";
|
||||
|
||||
public String getLastMethodEntered() {
|
||||
return this.lastEntry;
|
||||
}
|
||||
|
||||
@Pointcut("execution(* *(..))")
|
||||
public void methodExecution() {
|
||||
}
|
||||
|
||||
@Before("methodExecution()")
|
||||
public void entryTrace(JoinPoint jp) {
|
||||
this.lastEntry = jp.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
class DummyAspect {
|
||||
|
||||
@Around("execution(* setAge(int))")
|
||||
public Object test(ProceedingJoinPoint pjp) throws Throwable {
|
||||
return pjp.proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
class DummyAspectWithParameter {
|
||||
|
||||
@Around("execution(* setAge(int)) && args(age)")
|
||||
public Object test(ProceedingJoinPoint pjp, int age) throws Throwable {
|
||||
return pjp.proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DummyFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
@Order(10)
|
||||
class IncreaseReturnValue {
|
||||
|
||||
@Around("execution(int *.getAge())")
|
||||
public Object doubleReturnValue(ProceedingJoinPoint pjp) throws Throwable {
|
||||
int result = (Integer) pjp.proceed();
|
||||
return result + 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
class MultiplyReturnValue {
|
||||
|
||||
private int multiple = 2;
|
||||
|
||||
public int invocations;
|
||||
|
||||
public void setMultiple(int multiple) {
|
||||
this.multiple = multiple;
|
||||
}
|
||||
|
||||
public int getMultiple() {
|
||||
return this.multiple;
|
||||
}
|
||||
|
||||
@Around("execution(int *.getAge())")
|
||||
public Object doubleReturnValue(ProceedingJoinPoint pjp) throws Throwable {
|
||||
++this.invocations;
|
||||
int result = (Integer) pjp.proceed();
|
||||
return result * this.multiple;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
class RetryAspect {
|
||||
|
||||
private int beginCalls;
|
||||
|
||||
private int commitCalls;
|
||||
|
||||
private int rollbackCalls;
|
||||
|
||||
@Pointcut("execution(public * UnreliableBean.*(..))")
|
||||
public void execOfPublicMethod() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry Advice
|
||||
*/
|
||||
@Around("execOfPublicMethod()")
|
||||
public Object retry(ProceedingJoinPoint jp) throws Throwable {
|
||||
boolean retry = true;
|
||||
Object o = null;
|
||||
while (retry) {
|
||||
try {
|
||||
retry = false;
|
||||
this.beginCalls++;
|
||||
try {
|
||||
o = jp.proceed();
|
||||
this.commitCalls++;
|
||||
} catch (RetryableException e) {
|
||||
this.rollbackCalls++;
|
||||
throw e;
|
||||
}
|
||||
} catch (RetryableException re) {
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public int getBeginCalls() {
|
||||
return this.beginCalls;
|
||||
}
|
||||
|
||||
public int getCommitCalls() {
|
||||
return this.commitCalls;
|
||||
}
|
||||
|
||||
public int getRollbackCalls() {
|
||||
return this.rollbackCalls;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class RetryableException extends NestedRuntimeException {
|
||||
|
||||
public RetryableException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public RetryableException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
||||
class UnreliableBean {
|
||||
|
||||
private int calls;
|
||||
|
||||
public int unreliable() {
|
||||
this.calls++;
|
||||
if (this.calls % 2 != 0) {
|
||||
throw new RetryableException("foo");
|
||||
}
|
||||
return this.calls;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class TestBeanAdvisor extends StaticMethodMatcherPointcutAdvisor {
|
||||
|
||||
public int count;
|
||||
|
||||
public TestBeanAdvisor() {
|
||||
setAdvice(new MethodBeforeAdvice() {
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
++count;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return ITestBean.class.isAssignableFrom(targetClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.beans.TestBean"/>
|
||||
|
||||
<bean id="aspect" class="org.springframework.aop.aspectj.autoproxy.ExceptionHandlingAspect"/>
|
||||
|
||||
</beans>
|
||||
@@ -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.autoproxy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class AtAspectJAfterThrowingTests {
|
||||
|
||||
@Test
|
||||
public void testAccessThrowable() throws Exception {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
|
||||
ITestBean bean = (ITestBean) ctx.getBean("testBean");
|
||||
ExceptionHandlingAspect aspect = (ExceptionHandlingAspect) ctx.getBean("aspect");
|
||||
|
||||
assertTrue(AopUtils.isAopProxy(bean));
|
||||
try {
|
||||
bean.unreliableFileOperation();
|
||||
}
|
||||
catch (IOException e) {
|
||||
//
|
||||
}
|
||||
|
||||
assertEquals(1, aspect.handled);
|
||||
assertNotNull(aspect.lastException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
class ExceptionHandlingAspect {
|
||||
|
||||
public int handled;
|
||||
|
||||
public IOException lastException;
|
||||
|
||||
@AfterThrowing(pointcut = "within(org.springframework.beans.ITestBean+)", throwing = "ex")
|
||||
public void handleIOException(IOException ex) {
|
||||
handled++;
|
||||
lastException = ex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean id="testAspect" class="org.springframework.aop.aspectj.autoproxy.AtAspectJAnnotationBindingTestAspect"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.aop.aspectj.autoproxy.AnnotatedTestBeanImpl"/>
|
||||
|
||||
<bean id="arrayFactoryBean" class="org.springframework.aop.aspectj.autoproxy.ResourceArrayFactoryBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AtAspectJAnnotationBindingTests {
|
||||
|
||||
private AnnotatedTestBean testBean;
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
|
||||
testBean = (AnnotatedTestBean) ctx.getBean("testBean");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAnnotationBindingInAroundAdvice() {
|
||||
assertEquals("this value doThis", testBean.doThis());
|
||||
assertEquals("that value doThat", testBean.doThat());
|
||||
assertEquals(2, testBean.doArray().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingWithoutAnnotationPresent() {
|
||||
assertEquals("doTheOther", testBean.doTheOther());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointcutEvaulatedAgainstArray() {
|
||||
ctx.getBean("arrayFactoryBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
class AtAspectJAnnotationBindingTestAspect {
|
||||
|
||||
@Around("execution(* *(..)) && @annotation(testAnn)")
|
||||
public Object doWithAnnotation(ProceedingJoinPoint pjp, TestAnnotation testAnn)
|
||||
throws Throwable {
|
||||
String annValue = testAnn.value();
|
||||
Object result = pjp.proceed();
|
||||
return (result instanceof String ? annValue + " " + result : result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ResourceArrayFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
@TestAnnotation("some value")
|
||||
public Object getObject() throws Exception {
|
||||
return new Resource[0];
|
||||
}
|
||||
|
||||
@TestAnnotation("some value")
|
||||
public Class<?> getObjectType() {
|
||||
return Resource[].class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.autoproxy;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
|
||||
|
||||
/**
|
||||
* 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 { }
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
interface AnnotatedTestBean {
|
||||
|
||||
String doThis();
|
||||
|
||||
String doThat();
|
||||
|
||||
String doTheOther();
|
||||
|
||||
String[] doArray();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface TestAnnotation {
|
||||
String value() ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
class AnnotatedTestBeanImpl implements AnnotatedTestBean {
|
||||
|
||||
@TestAnnotation("this value")
|
||||
public String doThis() {
|
||||
return "doThis";
|
||||
}
|
||||
|
||||
@TestAnnotation("that value")
|
||||
public String doThat() {
|
||||
return "doThat";
|
||||
}
|
||||
|
||||
@TestAnnotation("array value")
|
||||
public String[] doArray() {
|
||||
return new String[] {"doThis", "doThat"};
|
||||
}
|
||||
|
||||
// not annotated
|
||||
public String doTheOther() {
|
||||
return "doTheOther";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
class AnnotationBindingTestAspect {
|
||||
|
||||
public String doWithAnnotation(ProceedingJoinPoint pjp, TestAnnotation testAnnotation) throws Throwable {
|
||||
return testAnnotation.value();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
|
||||
-->
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean
|
||||
class="org.springframework.aop.aspectj.autoproxy.MultiplyReturnValue" >
|
||||
<property name="multiple" value="2" />
|
||||
</bean>
|
||||
|
||||
<bean
|
||||
class="org.springframework.aop.aspectj.autoproxy.benchmark.TraceAspect" >
|
||||
</bean>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="adrian" />
|
||||
<property name="age" value="34" />
|
||||
</bean>
|
||||
|
||||
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
|
||||
-->
|
||||
|
||||
<aop:aspectj-autoproxy>
|
||||
<!-- Explicit testing the whitespace body variant here -->
|
||||
</aop:aspectj-autoproxy>
|
||||
|
||||
<bean class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
|
||||
<property name="advice" ref="multiplyReturnValueInterceptor" />
|
||||
<property name="mappedName" value="getAge" />
|
||||
</bean>
|
||||
|
||||
<bean id="multiplyReturnValueInterceptor"
|
||||
class="org.springframework.aop.aspectj.autoproxy.benchmark.MultiplyReturnValueInterceptor" >
|
||||
<property name="multiple" value="2" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.benchmark.TraceBeforeAdvice"
|
||||
factory-method="advisor" />
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.benchmark.TraceAfterReturningAdvice"
|
||||
factory-method="advisor" />
|
||||
|
||||
<bean class="org.springframework.aop.aspectj.autoproxy.benchmark.TraceAspect"/>
|
||||
|
||||
<bean id="adrian" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="adrian"/>
|
||||
<property name="age" value="34"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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.autoproxy.benchmark;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.AfterReturningAdvice;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.aop.support.StaticMethodMatcherPointcut;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
/**
|
||||
* Integration tests for AspectJ auto proxying. Includes mixing with Spring AOP
|
||||
* Advisors to demonstrate that existing autoproxying contract is honoured.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class BenchmarkTests {
|
||||
|
||||
private static final Class<?> CLASS = BenchmarkTests.class;
|
||||
|
||||
private static final String ASPECTJ_CONTEXT = CLASS.getSimpleName() + "-aspectj.xml";
|
||||
|
||||
private static final String SPRING_AOP_CONTEXT = CLASS.getSimpleName() + "-springAop.xml";
|
||||
|
||||
@Test
|
||||
public void testRepeatedAroundAdviceInvocationsWithAspectJ() {
|
||||
testRepeatedAroundAdviceInvocations(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAroundAdviceInvocationsWithSpringAop() {
|
||||
testRepeatedAroundAdviceInvocations(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedBeforeAdviceInvocationsWithAspectJ() {
|
||||
testBeforeAdviceWithoutJoinPoint(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedBeforeAdviceInvocationsWithSpringAop() {
|
||||
testBeforeAdviceWithoutJoinPoint(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAfterReturningAdviceInvocationsWithAspectJ() {
|
||||
testAfterReturningAdviceWithoutJoinPoint(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedAfterReturningAdviceInvocationsWithSpringAop() {
|
||||
testAfterReturningAdviceWithoutJoinPoint(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedMixWithAspectJ() {
|
||||
testMix(ASPECTJ_CONTEXT, getCount(), "AspectJ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatedMixWithSpringAop() {
|
||||
testMix(SPRING_AOP_CONTEXT, getCount(), "Spring AOP");
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the return number to a higher number to make this test useful.
|
||||
*/
|
||||
protected int getCount() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
private long testRepeatedAroundAdviceInvocations(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated around advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
assertEquals(68, adrian.getAge());
|
||||
|
||||
for (int i = 0; i < howmany; i++) {
|
||||
adrian.getAge();
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testBeforeAdviceWithoutJoinPoint(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated before advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
Advised a = (Advised) adrian;
|
||||
assertTrue(a.getAdvisors().length >= 3);
|
||||
assertEquals("adrian", adrian.getName());
|
||||
|
||||
for (int i = 0; i < howmany; i++) {
|
||||
adrian.getName();
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testAfterReturningAdviceWithoutJoinPoint(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated after returning advice invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
Advised a = (Advised) adrian;
|
||||
assertTrue(a.getAdvisors().length >= 3);
|
||||
// Hits joinpoint
|
||||
adrian.setAge(25);
|
||||
|
||||
for (int i = 0; i < howmany; i++) {
|
||||
adrian.setAge(i);
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long testMix(String file, int howmany, String technology) {
|
||||
ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext(file, CLASS);
|
||||
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start(howmany + " repeated mixed invocations with " + technology);
|
||||
ITestBean adrian = (ITestBean) bf.getBean("adrian");
|
||||
|
||||
assertTrue(AopUtils.isAopProxy(adrian));
|
||||
Advised a = (Advised) adrian;
|
||||
assertTrue(a.getAdvisors().length >= 3);
|
||||
|
||||
for (int i = 0; i < howmany; i++) {
|
||||
// Hit all 3 joinpoints
|
||||
adrian.getAge();
|
||||
adrian.getName();
|
||||
adrian.setAge(i);
|
||||
|
||||
// Invoke three non-advised methods
|
||||
adrian.getDoctor();
|
||||
adrian.getLawyer();
|
||||
adrian.getSpouse();
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
System.out.println(sw.prettyPrint());
|
||||
return sw.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class MultiplyReturnValueInterceptor implements MethodInterceptor {
|
||||
|
||||
private int multiple = 2;
|
||||
|
||||
public int invocations;
|
||||
|
||||
public void setMultiple(int multiple) {
|
||||
this.multiple = multiple;
|
||||
}
|
||||
|
||||
public int getMultiple() {
|
||||
return this.multiple;
|
||||
}
|
||||
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
++invocations;
|
||||
int result = (Integer) mi.proceed();
|
||||
return result * this.multiple;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TraceAfterReturningAdvice implements AfterReturningAdvice {
|
||||
|
||||
public int afterTakesInt;
|
||||
|
||||
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
|
||||
++afterTakesInt;
|
||||
}
|
||||
|
||||
public static Advisor advisor() {
|
||||
return new DefaultPointcutAdvisor(
|
||||
new StaticMethodMatcherPointcut() {
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getParameterTypes().length == 1 &&
|
||||
method.getParameterTypes()[0].equals(Integer.class);
|
||||
}
|
||||
},
|
||||
new TraceAfterReturningAdvice());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
class TraceAspect {
|
||||
|
||||
public int beforeStringReturn;
|
||||
|
||||
public int afterTakesInt;
|
||||
|
||||
@Before("execution(String *.*(..))")
|
||||
public void traceWithoutJoinPoint() {
|
||||
++beforeStringReturn;
|
||||
}
|
||||
|
||||
@AfterReturning("execution(void *.*(int))")
|
||||
public void traceWithoutJoinPoint2() {
|
||||
++afterTakesInt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TraceBeforeAdvice implements MethodBeforeAdvice {
|
||||
|
||||
public int beforeStringReturn;
|
||||
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
++beforeStringReturn;
|
||||
}
|
||||
|
||||
public static Advisor advisor() {
|
||||
return new DefaultPointcutAdvisor(
|
||||
new StaticMethodMatcherPointcut() {
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getReturnType().equals(String.class);
|
||||
}
|
||||
},
|
||||
new TraceBeforeAdvice());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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.autoproxy.spr3064;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class SPR3064Tests {
|
||||
|
||||
private Service service;
|
||||
|
||||
@Test
|
||||
public void testServiceIsAdvised() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml", getClass());
|
||||
|
||||
service = (Service) ctx.getBean("service");
|
||||
|
||||
try {
|
||||
this.service.serveMe();
|
||||
fail("service operation has not been advised by transaction interceptor");
|
||||
}
|
||||
catch(RuntimeException ex) {
|
||||
assertEquals("advice invoked",ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface Transaction {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
class TransactionInterceptor {
|
||||
|
||||
@Around(value="execution(* *..Service.*(..)) && @annotation(transaction)")
|
||||
public Object around(ProceedingJoinPoint pjp, Transaction transaction) throws Throwable {
|
||||
throw new RuntimeException("advice invoked");
|
||||
//return pjp.proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface Service {
|
||||
|
||||
void serveMe();
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ServiceImpl implements Service {
|
||||
|
||||
@Transaction
|
||||
public void serveMe() {
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user