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,32 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
|
||||
|
||||
public void testNoAutoproxyingOfAjcCompiledAspects() {
|
||||
new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public aspect CodeStyleAspect {
|
||||
|
||||
private String foo;
|
||||
|
||||
pointcut somePC() : call(* someMethod());
|
||||
|
||||
before() : somePC() {
|
||||
System.out.println("match");
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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/>
|
||||
|
||||
<bean id="myAspect" class="org.springframework.aop.aspectj.autoproxy.CodeStyleAspect"
|
||||
factory-method="aspectOf">
|
||||
<property name="foo" value="bar"/>
|
||||
</bean>
|
||||
|
||||
<bean id="otherBean" class="java.lang.Object"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import org.springframework.core.enums.ShortCodedLabeledEnum;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class Colour extends ShortCodedLabeledEnum {
|
||||
|
||||
public static final Colour RED = new Colour(0, "RED");
|
||||
public static final Colour BLUE = new Colour(1, "BLUE");
|
||||
public static final Colour GREEN = new Colour(2, "GREEN");
|
||||
public static final Colour PURPLE = new Colour(3, "PURPLE");
|
||||
|
||||
private Colour(int code, String label) {
|
||||
super(code, label);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 21.08.2003
|
||||
*/
|
||||
public class DerivedTestBean extends TestBean implements Serializable, BeanNameAware, DisposableBean {
|
||||
|
||||
private String beanName;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
|
||||
public DerivedTestBean() {
|
||||
}
|
||||
|
||||
public DerivedTestBean(String[] names) {
|
||||
if (names == null || names.length < 2) {
|
||||
throw new IllegalArgumentException("Invalid names array");
|
||||
}
|
||||
setName(names[0]);
|
||||
setBeanName(names[1]);
|
||||
}
|
||||
|
||||
public static DerivedTestBean create(String[] names) {
|
||||
return new DerivedTestBean(names);
|
||||
}
|
||||
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
if (this.beanName == null || beanName == null) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
public void setSpouseRef(String name) {
|
||||
setSpouse(new TestBean(name));
|
||||
}
|
||||
|
||||
|
||||
public void initialize() {
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
public boolean wasInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
public boolean wasDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.beans;
|
||||
|
||||
public interface INestedTestBean {
|
||||
|
||||
public String getCompany();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
/*
|
||||
* Copyright 2002-2005 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.beans;
|
||||
|
||||
public interface IOther {
|
||||
|
||||
void absquatulate();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface used for {@link org.springframework.beans.TestBean}.
|
||||
*
|
||||
* <p>Two methods are the same as on Person, but if this
|
||||
* extends person it breaks quite a few tests..
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public interface ITestBean {
|
||||
|
||||
int getAge();
|
||||
|
||||
void setAge(int age);
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
ITestBean getSpouse();
|
||||
|
||||
void setSpouse(ITestBean spouse);
|
||||
|
||||
ITestBean[] getSpouses();
|
||||
|
||||
String[] getStringArray();
|
||||
|
||||
void setStringArray(String[] stringArray);
|
||||
|
||||
/**
|
||||
* Throws a given (non-null) exception.
|
||||
*/
|
||||
void exceptional(Throwable t) throws Throwable;
|
||||
|
||||
Object returnsThis();
|
||||
|
||||
INestedTestBean getDoctor();
|
||||
|
||||
INestedTestBean getLawyer();
|
||||
|
||||
IndexedTestBean getNestedIndexedBean();
|
||||
|
||||
/**
|
||||
* Increment the age by one.
|
||||
* @return the previous age
|
||||
*/
|
||||
int haveBirthday();
|
||||
|
||||
void unreliableFileOperation() throws IOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 11.11.2003
|
||||
*/
|
||||
public class IndexedTestBean {
|
||||
|
||||
private TestBean[] array;
|
||||
|
||||
private Collection collection;
|
||||
|
||||
private List list;
|
||||
|
||||
private Set set;
|
||||
|
||||
private SortedSet sortedSet;
|
||||
|
||||
private Map map;
|
||||
|
||||
private SortedMap sortedMap;
|
||||
|
||||
|
||||
public IndexedTestBean() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public IndexedTestBean(boolean populate) {
|
||||
if (populate) {
|
||||
populate();
|
||||
}
|
||||
}
|
||||
|
||||
public void populate() {
|
||||
TestBean tb0 = new TestBean("name0", 0);
|
||||
TestBean tb1 = new TestBean("name1", 0);
|
||||
TestBean tb2 = new TestBean("name2", 0);
|
||||
TestBean tb3 = new TestBean("name3", 0);
|
||||
TestBean tb4 = new TestBean("name4", 0);
|
||||
TestBean tb5 = new TestBean("name5", 0);
|
||||
TestBean tb6 = new TestBean("name6", 0);
|
||||
TestBean tb7 = new TestBean("name7", 0);
|
||||
TestBean tbX = new TestBean("nameX", 0);
|
||||
TestBean tbY = new TestBean("nameY", 0);
|
||||
this.array = new TestBean[] {tb0, tb1};
|
||||
this.list = new ArrayList();
|
||||
this.list.add(tb2);
|
||||
this.list.add(tb3);
|
||||
this.set = new TreeSet();
|
||||
this.set.add(tb6);
|
||||
this.set.add(tb7);
|
||||
this.map = new HashMap();
|
||||
this.map.put("key1", tb4);
|
||||
this.map.put("key2", tb5);
|
||||
this.map.put("key.3", tb5);
|
||||
List list = new ArrayList();
|
||||
list.add(tbX);
|
||||
list.add(tbY);
|
||||
this.map.put("key4", list);
|
||||
}
|
||||
|
||||
|
||||
public TestBean[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setArray(TestBean[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public Collection getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(Collection collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public Set getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(Set set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public SortedSet getSortedSet() {
|
||||
return sortedSet;
|
||||
}
|
||||
|
||||
public void setSortedSet(SortedSet sortedSet) {
|
||||
this.sortedSet = sortedSet;
|
||||
}
|
||||
|
||||
public Map getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public SortedMap getSortedMap() {
|
||||
return sortedMap;
|
||||
}
|
||||
|
||||
public void setSortedMap(SortedMap sortedMap) {
|
||||
this.sortedMap = sortedMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.beans;
|
||||
|
||||
/**
|
||||
* Simple nested test bean used for testing bean factories, AOP framework etc.
|
||||
*
|
||||
* @author Trevor D. Cook
|
||||
* @since 30.09.2003
|
||||
*/
|
||||
public class NestedTestBean implements INestedTestBean {
|
||||
|
||||
private String company = "";
|
||||
|
||||
public NestedTestBean() {
|
||||
}
|
||||
|
||||
public NestedTestBean(String company) {
|
||||
setCompany(company);
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = (company != null ? company : "");
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NestedTestBean)) {
|
||||
return false;
|
||||
}
|
||||
NestedTestBean ntb = (NestedTestBean) obj;
|
||||
return this.company.equals(ntb.company);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.company.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NestedTestBean: " + this.company;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Simple test bean used for testing bean factories, the AOP framework etc.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 15 April 2001
|
||||
*/
|
||||
public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOther, Comparable {
|
||||
|
||||
private String beanName;
|
||||
|
||||
private String country;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private boolean postProcessed;
|
||||
|
||||
private String name;
|
||||
|
||||
private String sex;
|
||||
|
||||
private int age;
|
||||
|
||||
private boolean jedi;
|
||||
|
||||
private ITestBean[] spouses;
|
||||
|
||||
private String touchy;
|
||||
|
||||
private String[] stringArray;
|
||||
|
||||
private Integer[] someIntegerArray;
|
||||
|
||||
private Date date = new Date();
|
||||
|
||||
private Float myFloat = new Float(0.0);
|
||||
|
||||
private Collection friends = new LinkedList();
|
||||
|
||||
private Set someSet = new HashSet();
|
||||
|
||||
private Map someMap = new HashMap();
|
||||
|
||||
private List someList = new ArrayList();
|
||||
|
||||
private Properties someProperties = new Properties();
|
||||
|
||||
private INestedTestBean doctor = new NestedTestBean();
|
||||
|
||||
private INestedTestBean lawyer = new NestedTestBean();
|
||||
|
||||
private IndexedTestBean nestedIndexedBean;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
private Number someNumber;
|
||||
|
||||
private Colour favouriteColour;
|
||||
|
||||
private Boolean someBoolean;
|
||||
|
||||
private List otherColours;
|
||||
|
||||
private List pets;
|
||||
|
||||
|
||||
public TestBean() {
|
||||
}
|
||||
|
||||
public TestBean(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
}
|
||||
|
||||
public TestBean(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse, Properties someProperties) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
public TestBean(List someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
|
||||
public TestBean(Set someSet) {
|
||||
this.someSet = someSet;
|
||||
}
|
||||
|
||||
public TestBean(Map someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public TestBean(Properties someProperties) {
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public BeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public void setPostProcessed(boolean postProcessed) {
|
||||
this.postProcessed = postProcessed;
|
||||
}
|
||||
|
||||
public boolean isPostProcessed() {
|
||||
return postProcessed;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
if (this.name == null) {
|
||||
this.name = sex;
|
||||
}
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public boolean isJedi() {
|
||||
return jedi;
|
||||
}
|
||||
|
||||
public void setJedi(boolean jedi) {
|
||||
this.jedi = jedi;
|
||||
}
|
||||
|
||||
public ITestBean getSpouse() {
|
||||
return (spouses != null ? spouses[0] : null);
|
||||
}
|
||||
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
}
|
||||
|
||||
public ITestBean[] getSpouses() {
|
||||
return spouses;
|
||||
}
|
||||
|
||||
public String getTouchy() {
|
||||
return touchy;
|
||||
}
|
||||
|
||||
public void setTouchy(String touchy) throws Exception {
|
||||
if (touchy.indexOf('.') != -1) {
|
||||
throw new Exception("Can't contain a .");
|
||||
}
|
||||
if (touchy.indexOf(',') != -1) {
|
||||
throw new NumberFormatException("Number format exception: contains a ,");
|
||||
}
|
||||
this.touchy = touchy;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String[] getStringArray() {
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
public void setStringArray(String[] stringArray) {
|
||||
this.stringArray = stringArray;
|
||||
}
|
||||
|
||||
public Integer[] getSomeIntegerArray() {
|
||||
return someIntegerArray;
|
||||
}
|
||||
|
||||
public void setSomeIntegerArray(Integer[] someIntegerArray) {
|
||||
this.someIntegerArray = someIntegerArray;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Float getMyFloat() {
|
||||
return myFloat;
|
||||
}
|
||||
|
||||
public void setMyFloat(Float myFloat) {
|
||||
this.myFloat = myFloat;
|
||||
}
|
||||
|
||||
public Collection getFriends() {
|
||||
return friends;
|
||||
}
|
||||
|
||||
public void setFriends(Collection friends) {
|
||||
this.friends = friends;
|
||||
}
|
||||
|
||||
public Set getSomeSet() {
|
||||
return someSet;
|
||||
}
|
||||
|
||||
public void setSomeSet(Set someSet) {
|
||||
this.someSet = someSet;
|
||||
}
|
||||
|
||||
public Map getSomeMap() {
|
||||
return someMap;
|
||||
}
|
||||
|
||||
public void setSomeMap(Map someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public List getSomeList() {
|
||||
return someList;
|
||||
}
|
||||
|
||||
public void setSomeList(List someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
|
||||
public Properties getSomeProperties() {
|
||||
return someProperties;
|
||||
}
|
||||
|
||||
public void setSomeProperties(Properties someProperties) {
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
public INestedTestBean getDoctor() {
|
||||
return doctor;
|
||||
}
|
||||
|
||||
public void setDoctor(INestedTestBean doctor) {
|
||||
this.doctor = doctor;
|
||||
}
|
||||
|
||||
public INestedTestBean getLawyer() {
|
||||
return lawyer;
|
||||
}
|
||||
|
||||
public void setLawyer(INestedTestBean lawyer) {
|
||||
this.lawyer = lawyer;
|
||||
}
|
||||
|
||||
public Number getSomeNumber() {
|
||||
return someNumber;
|
||||
}
|
||||
|
||||
public void setSomeNumber(Number someNumber) {
|
||||
this.someNumber = someNumber;
|
||||
}
|
||||
|
||||
public Colour getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
public void setFavouriteColour(Colour favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public Boolean getSomeBoolean() {
|
||||
return someBoolean;
|
||||
}
|
||||
|
||||
public void setSomeBoolean(Boolean someBoolean) {
|
||||
this.someBoolean = someBoolean;
|
||||
}
|
||||
|
||||
public IndexedTestBean getNestedIndexedBean() {
|
||||
return nestedIndexedBean;
|
||||
}
|
||||
|
||||
public void setNestedIndexedBean(IndexedTestBean nestedIndexedBean) {
|
||||
this.nestedIndexedBean = nestedIndexedBean;
|
||||
}
|
||||
|
||||
public List getOtherColours() {
|
||||
return otherColours;
|
||||
}
|
||||
|
||||
public void setOtherColours(List otherColours) {
|
||||
this.otherColours = otherColours;
|
||||
}
|
||||
|
||||
public List getPets() {
|
||||
return pets;
|
||||
}
|
||||
|
||||
public void setPets(List pets) {
|
||||
this.pets = pets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.ITestBean#exceptional(Throwable)
|
||||
*/
|
||||
public void exceptional(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
public void unreliableFileOperation() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
/**
|
||||
* @see org.springframework.beans.ITestBean#returnsThis()
|
||||
*/
|
||||
public Object returnsThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.IOther#absquatulate()
|
||||
*/
|
||||
public void absquatulate() {
|
||||
}
|
||||
|
||||
public int haveBirthday() {
|
||||
return age++;
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
public boolean wasDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !(other instanceof TestBean)) {
|
||||
return false;
|
||||
}
|
||||
TestBean tb2 = (TestBean) other;
|
||||
return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.age;
|
||||
}
|
||||
|
||||
public int compareTo(Object other) {
|
||||
if (this.name != null && other instanceof TestBean) {
|
||||
return this.name.compareTo(((TestBean) other).getName());
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* 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 org.springframework.beans.factory.aspectj;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.mail.MailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public abstract class AbstractBeanConfigurerTests extends TestCase {
|
||||
|
||||
protected ConfigurableApplicationContext context;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
this.context = createContext();
|
||||
}
|
||||
|
||||
protected abstract ConfigurableApplicationContext createContext();
|
||||
|
||||
public void testConfigurableWithExplicitBeanName() {
|
||||
ShouldBeConfiguredBySpring myObject = new ShouldBeConfiguredBySpring();
|
||||
assertEquals("Rod", myObject.getName());
|
||||
}
|
||||
|
||||
public void testWithoutAnnotation() {
|
||||
ShouldNotBeConfiguredBySpring myObject = new ShouldNotBeConfiguredBySpring();
|
||||
assertNull("Name should not have been set", myObject.getName());
|
||||
}
|
||||
|
||||
public void testConfigurableWithImplicitBeanName() {
|
||||
ShouldBeConfiguredBySpringUsingTypeNameAsBeanName myObject =
|
||||
new ShouldBeConfiguredBySpringUsingTypeNameAsBeanName();
|
||||
assertEquals("Rob", myObject.getName());
|
||||
}
|
||||
|
||||
public void testConfigurableUsingAutowireByType() {
|
||||
ShouldBeConfiguredBySpringUsingAutowireByType myObject =
|
||||
new ShouldBeConfiguredBySpringUsingAutowireByType();
|
||||
assertNotNull(myObject.getFriend());
|
||||
assertEquals("Ramnivas", myObject.getFriend().getName());
|
||||
}
|
||||
|
||||
public void testConfigurableUsingAutowireByName() {
|
||||
ValidAutowireByName myObject = new ValidAutowireByName();
|
||||
assertNotNull(myObject.getRamnivas());
|
||||
assertEquals("Ramnivas", myObject.getRamnivas().getName());
|
||||
}
|
||||
|
||||
public void testInvalidAutowireByName() {
|
||||
try {
|
||||
new InvalidAutowireByName();
|
||||
fail("Autowire by name cannot work");
|
||||
}
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testNewAspectAppliesToArbitraryNonAnnotatedPojo() {
|
||||
ArbitraryExistingPojo aep = new ArbitraryExistingPojo();
|
||||
assertNotNull(aep.friend);
|
||||
assertEquals("Ramnivas", aep.friend.getName());
|
||||
}
|
||||
|
||||
public void testNewAspectThatWasNotAddedToSpringContainer() {
|
||||
try{
|
||||
new ClassThatWillNotActuallyBeWired();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("BeanFactory") != -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInjectionOnDeserialization() throws Exception {
|
||||
ShouldBeConfiguredBySpring domainObject = new ShouldBeConfiguredBySpring();
|
||||
domainObject.setName("Anonymous");
|
||||
ShouldBeConfiguredBySpring deserializedDomainObject =
|
||||
serializeAndDeserialize(domainObject);
|
||||
assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
|
||||
}
|
||||
|
||||
public void testInjectionOnDeserializationForClassesThatContainsPublicReadResolve() throws Exception {
|
||||
ShouldBeConfiguredBySpringContainsPublicReadResolve domainObject = new ShouldBeConfiguredBySpringContainsPublicReadResolve();
|
||||
domainObject.setName("Anonymous");
|
||||
ShouldBeConfiguredBySpringContainsPublicReadResolve deserializedDomainObject =
|
||||
serializeAndDeserialize(domainObject);
|
||||
assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
|
||||
assertEquals("User readResolve should take precedence", 1, deserializedDomainObject.readResolveInvocationCount);
|
||||
}
|
||||
|
||||
// See ShouldBeConfiguredBySpringContainsPrivateReadResolve
|
||||
// public void testInjectionOnDeserializationForClassesThatContainsPrivateReadResolve() throws Exception {
|
||||
// ShouldBeConfiguredBySpringContainsPrivateReadResolve domainObject = new ShouldBeConfiguredBySpringContainsPrivateReadResolve();
|
||||
// domainObject.setName("Anonymous");
|
||||
// ShouldBeConfiguredBySpringContainsPrivateReadResolve deserializedDomainObject =
|
||||
// serializeAndDeserialize(domainObject);
|
||||
// assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
|
||||
// }
|
||||
|
||||
public void testNonInjectionOnDeserializationForSerializedButNotConfigured() throws Exception {
|
||||
SerializableThatShouldNotBeConfiguredBySpring domainObject = new SerializableThatShouldNotBeConfiguredBySpring();
|
||||
domainObject.setName("Anonymous");
|
||||
SerializableThatShouldNotBeConfiguredBySpring deserializedDomainObject =
|
||||
serializeAndDeserialize(domainObject);
|
||||
assertEquals("Dependency injected on deserialization","Anonymous",deserializedDomainObject.getName());
|
||||
}
|
||||
|
||||
public void testSubBeanConfiguredOnlyOnce() throws Exception {
|
||||
SubBean subBean = new SubBean();
|
||||
assertEquals("Property injected more than once", 1, subBean.setterCount);
|
||||
}
|
||||
|
||||
public void testSubBeanConfiguredOnlyOnceForPreConstruction() throws Exception {
|
||||
SubBeanPreConstruction subBean = new SubBeanPreConstruction();
|
||||
assertEquals("Property injected more than once", 1, subBean.setterCount);
|
||||
}
|
||||
|
||||
public void testSubSerializableBeanConfiguredOnlyOnce() throws Exception {
|
||||
SubSerializableBean subBean = new SubSerializableBean();
|
||||
assertEquals("Property injected more than once", 1, subBean.setterCount);
|
||||
subBean.setterCount = 0;
|
||||
|
||||
SubSerializableBean deserializedSubBean = serializeAndDeserialize(subBean);
|
||||
assertEquals("Property injected more than once", 1, deserializedSubBean.setterCount);
|
||||
}
|
||||
|
||||
public void testPreConstructionConfiguredBean() {
|
||||
PreConstructionConfiguredBean bean = new PreConstructionConfiguredBean();
|
||||
assertTrue("Injection didn't occur before construction", bean.preConstructionConfigured);
|
||||
}
|
||||
|
||||
public void testPreConstructionConfiguredBeanDeserializationReinjection() throws Exception {
|
||||
PreConstructionConfiguredBean bean = new PreConstructionConfiguredBean();
|
||||
PreConstructionConfiguredBean deserialized = serializeAndDeserialize(bean);
|
||||
assertEquals("Injection didn't occur upon deserialization", "ramnivas", deserialized.getName());
|
||||
}
|
||||
|
||||
public void testPostConstructionConfiguredBean() {
|
||||
PostConstructionConfiguredBean bean = new PostConstructionConfiguredBean();
|
||||
assertFalse("Injection occurred before construction", bean.preConstructionConfigured);
|
||||
}
|
||||
|
||||
public void testPostConstructionConfiguredBeanDeserializationReinjection() throws Exception {
|
||||
PostConstructionConfiguredBean bean = new PostConstructionConfiguredBean();
|
||||
PostConstructionConfiguredBean deserialized = serializeAndDeserialize(bean);
|
||||
assertEquals("Injection didn't occur upon deserialization", "ramnivas", deserialized.getName());
|
||||
}
|
||||
|
||||
public void testInterfaceDrivenDependencyInjection() {
|
||||
MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
|
||||
Order testOrder = new Order();
|
||||
assertNotNull("Interface driven injection didn't occur for direct construction", testOrder.mailSender);
|
||||
}
|
||||
|
||||
public void testGenericInterfaceDrivenDependencyInjection() {
|
||||
PricingStrategy injectedPricingStrategy = new PricingStrategy();
|
||||
PricingStrategyDependencyInjectionAspect.aspectOf().setPricingStrategy(injectedPricingStrategy);
|
||||
LineItem testLineItem = new LineItem();
|
||||
assertSame("Generic interface driven injection didn't occur for direct construction", injectedPricingStrategy, testLineItem.pricingStrategy);
|
||||
}
|
||||
|
||||
public void testInterfaceDrivenDependencyInjectionMultipleInterfaces() {
|
||||
MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
|
||||
PaymentProcessorDependencyInjectionAspect.aspectOf().setPaymentProcessor(new PaymentProcessor());
|
||||
|
||||
ShoppingCart testCart = new ShoppingCart();
|
||||
|
||||
assertNotNull("Interface driven injection didn't occur for direct construction", testCart.mailSender);
|
||||
assertNotNull("Interface driven injection didn't occur for direct construction", testCart.paymentProcessor);
|
||||
}
|
||||
|
||||
public void testInterfaceDrivenDependencyInjectionUponDeserialization() throws Exception {
|
||||
MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
|
||||
Order testOrder = new Order();
|
||||
Order deserializedOrder = serializeAndDeserialize(testOrder);
|
||||
assertNotNull("Interface driven injection didn't occur for deserialization", testOrder.mailSender);
|
||||
}
|
||||
|
||||
public void testFieldAutoWiredAnnotationInjection() {
|
||||
FieldAutoWiredServiceBean bean = new FieldAutoWiredServiceBean();
|
||||
assertNotNull(bean.testService);
|
||||
}
|
||||
|
||||
public void testMethodAutoWiredAnnotationInjection() {
|
||||
MethodAutoWiredServiceBean bean = new MethodAutoWiredServiceBean();
|
||||
assertNotNull(bean.testService);
|
||||
}
|
||||
|
||||
public void testMultiArgumentMethodAutoWiredAnnotationInjection() {
|
||||
MultiArgumentMethodAutoWiredServiceBean bean = new MultiArgumentMethodAutoWiredServiceBean();
|
||||
assertNotNull(bean.testService);
|
||||
assertNotNull(bean.paymentService);
|
||||
}
|
||||
|
||||
public void testGenericParameterConfigurableBean() {
|
||||
GenericParameterConfigurableBean bean = new GenericParameterConfigurableBean();
|
||||
assertNotNull(bean.testService);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T serializeAndDeserialize(T serializable) throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(serializable);
|
||||
oos.close();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
return (T)ois.readObject();
|
||||
}
|
||||
|
||||
|
||||
@Configurable("beanOne")
|
||||
protected static class ShouldBeConfiguredBySpring implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable("beanOne")
|
||||
private static class ShouldBeConfiguredBySpringContainsPublicReadResolve implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
private int readResolveInvocationCount = 0;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Object readResolve() throws ObjectStreamException {
|
||||
readResolveInvocationCount++;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// Won't work until we use hasmethod() experimental pointcut in AspectJ.
|
||||
// @Configurable("beanOne")
|
||||
// private static class ShouldBeConfiguredBySpringContainsPrivateReadResolve implements Serializable {
|
||||
//
|
||||
// private String name;
|
||||
//
|
||||
// public void setName(String name) {
|
||||
// this.name = name;
|
||||
// }
|
||||
//
|
||||
// public String getName() {
|
||||
// return this.name;
|
||||
// }
|
||||
//
|
||||
// private Object readResolve() throws ObjectStreamException {
|
||||
// return this;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
private static class ShouldNotBeConfiguredBySpring {
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SerializableThatShouldNotBeConfiguredBySpring implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable
|
||||
private static class ShouldBeConfiguredBySpringUsingTypeNameAsBeanName {
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable(autowire=Autowire.BY_TYPE)
|
||||
private static class ShouldBeConfiguredBySpringUsingAutowireByType {
|
||||
|
||||
private TestBean friend = null;
|
||||
|
||||
public TestBean getFriend() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
public void setFriend(TestBean friend) {
|
||||
this.friend = friend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable(autowire=Autowire.BY_NAME)
|
||||
private static class ValidAutowireByName {
|
||||
|
||||
private TestBean friend = null;
|
||||
|
||||
public TestBean getRamnivas() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
public void setRamnivas(TestBean friend) {
|
||||
this.friend = friend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable(autowire=Autowire.BY_NAME, dependencyCheck=true)
|
||||
private static class InvalidAutowireByName {
|
||||
|
||||
private TestBean friend;
|
||||
|
||||
public TestBean getFriend() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
public void setFriend(TestBean friend) {
|
||||
this.friend = friend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class ArbitraryExistingPojo {
|
||||
|
||||
private TestBean friend;
|
||||
|
||||
public void setFriend(TestBean f) {
|
||||
this.friend = f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CircularFactoryBean implements FactoryBean{
|
||||
|
||||
public CircularFactoryBean() {
|
||||
ValidAutowireByName autowired = new ValidAutowireByName();
|
||||
assertNull(autowired.getRamnivas());
|
||||
}
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable
|
||||
private static class BaseBean {
|
||||
|
||||
public int setterCount;
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
setterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SubBean extends BaseBean {
|
||||
}
|
||||
|
||||
@Configurable(preConstruction=true)
|
||||
private static class SubBeanPreConstruction extends BaseBean {
|
||||
}
|
||||
|
||||
@Configurable
|
||||
private static class BaseSerializableBean implements Serializable {
|
||||
|
||||
public int setterCount;
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
setterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SubSerializableBean extends BaseSerializableBean {
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
private static class WireArbitraryExistingPojo extends AbstractBeanConfigurerAspect {
|
||||
|
||||
@Pointcut("initialization(ArbitraryExistingPojo.new(..)) && this(beanInstance)")
|
||||
protected void beanCreation(Object beanInstance){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
private static class AspectThatWillNotBeUsed extends AbstractBeanConfigurerAspect {
|
||||
|
||||
@Pointcut("initialization(ClassThatWillNotActuallyBeWired.new(..)) && this(beanInstance)")
|
||||
protected void beanCreation(Object beanInstance){
|
||||
}
|
||||
}
|
||||
|
||||
private static aspect MailClientDependencyInjectionAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
||||
private MailSender mailSender;
|
||||
|
||||
public pointcut inConfigurableBean() : within(MailSenderClient+);
|
||||
|
||||
public void configureBean(Object bean) {
|
||||
((MailSenderClient)bean).setMailSender(this.mailSender);
|
||||
}
|
||||
|
||||
declare parents: MailSenderClient implements ConfigurableObject;
|
||||
|
||||
public void setMailSender(MailSender mailSender) {
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
}
|
||||
|
||||
private static aspect PaymentProcessorDependencyInjectionAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
||||
private PaymentProcessor paymentProcessor;
|
||||
|
||||
public pointcut inConfigurableBean() : within(PaymentProcessorClient+);
|
||||
|
||||
public void configureBean(Object bean) {
|
||||
((PaymentProcessorClient)bean).setPaymentProcessor(this.paymentProcessor);
|
||||
}
|
||||
|
||||
declare parents: PaymentProcessorClient implements ConfigurableObject;
|
||||
|
||||
public void setPaymentProcessor(PaymentProcessor paymentProcessor) {
|
||||
this.paymentProcessor = paymentProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
private static aspect PricingStrategyDependencyInjectionAspect extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
|
||||
private PricingStrategy pricingStrategy;
|
||||
|
||||
public void configure(PricingStrategyClient bean) {
|
||||
bean.setPricingStrategy(pricingStrategy);
|
||||
}
|
||||
|
||||
public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
||||
this.pricingStrategy = pricingStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface MailSenderClient {
|
||||
public void setMailSender(MailSender mailSender);
|
||||
}
|
||||
|
||||
public static interface PaymentProcessorClient {
|
||||
public void setPaymentProcessor(PaymentProcessor paymentProcessor);
|
||||
}
|
||||
|
||||
public static class PaymentProcessor {
|
||||
|
||||
}
|
||||
|
||||
public static interface PricingStrategyClient {
|
||||
public void setPricingStrategy(PricingStrategy pricingStrategy);
|
||||
}
|
||||
|
||||
public static class PricingStrategy {
|
||||
|
||||
}
|
||||
|
||||
public static class LineItem implements PricingStrategyClient {
|
||||
private PricingStrategy pricingStrategy;
|
||||
|
||||
public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
||||
this.pricingStrategy = pricingStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Order implements MailSenderClient, Serializable {
|
||||
private transient MailSender mailSender;
|
||||
|
||||
public void setMailSender(MailSender mailSender) {
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ShoppingCart implements MailSenderClient, PaymentProcessorClient {
|
||||
private transient MailSender mailSender;
|
||||
private transient PaymentProcessor paymentProcessor;
|
||||
|
||||
public void setMailSender(MailSender mailSender) {
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
public void setPaymentProcessor(PaymentProcessor paymentProcessor) {
|
||||
this.paymentProcessor = paymentProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassThatWillNotActuallyBeWired {
|
||||
|
||||
}
|
||||
|
||||
@Configurable
|
||||
private static class PreOrPostConstructionConfiguredBean implements Serializable {
|
||||
private transient String name;
|
||||
protected transient boolean preConstructionConfigured;
|
||||
transient int count;
|
||||
|
||||
public PreOrPostConstructionConfiguredBean() {
|
||||
preConstructionConfigured = (this.name != null);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configurable(preConstruction=true)
|
||||
public static class PreConstructionConfiguredBean extends PreOrPostConstructionConfiguredBean {
|
||||
}
|
||||
|
||||
|
||||
@Configurable(preConstruction=false)
|
||||
private static class PostConstructionConfiguredBean extends PreOrPostConstructionConfiguredBean {
|
||||
}
|
||||
|
||||
@Configurable
|
||||
public static class FieldAutoWiredServiceBean {
|
||||
@Autowired transient private TestService testService;
|
||||
}
|
||||
|
||||
@Configurable
|
||||
public static class MethodAutoWiredServiceBean {
|
||||
transient private TestService testService;
|
||||
|
||||
@Autowired
|
||||
public void setTestService(TestService testService) {
|
||||
this.testService = testService;
|
||||
}
|
||||
}
|
||||
|
||||
@Configurable
|
||||
public static class MultiArgumentMethodAutoWiredServiceBean {
|
||||
transient private TestService testService;
|
||||
transient private PaymentService paymentService;
|
||||
|
||||
@Autowired
|
||||
public void setDependencies(TestService testService, PaymentService paymentService) {
|
||||
this.testService = testService;
|
||||
this.paymentService = paymentService;
|
||||
}
|
||||
}
|
||||
|
||||
@Configurable
|
||||
public static class GenericParameterConfigurableBean {
|
||||
private TestService testService;
|
||||
|
||||
public void setTestService(TestService testService) {
|
||||
this.testService = testService;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestService {
|
||||
|
||||
}
|
||||
|
||||
public static class PaymentService {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 org.springframework.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
/**
|
||||
* Tests that @EnableSpringConfigured properly registers an
|
||||
* {@link AnnotationBeanConfigurerAspect}, just as does {@code <context:spring-configured>}
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class AnnotationBeanConfigurerTests extends AbstractBeanConfigurerTests {
|
||||
|
||||
@Override
|
||||
protected ConfigurableApplicationContext createContext() {
|
||||
return new AnnotationConfigApplicationContext(Config.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("org/springframework/beans/factory/aspectj/beanConfigurerTests-beans.xml")
|
||||
@EnableSpringConfigured
|
||||
static class Config {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SpringConfiguredWithAutoProxyingTests extends TestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
||||
}
|
||||
|
||||
public void testSpringConfiguredAndAutoProxyUsedTogether() {
|
||||
; // set up is sufficient to trigger failure if this is going to fail...
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 org.springframework.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class XmlBeanConfigurerTests extends AbstractBeanConfigurerTests {
|
||||
|
||||
@Override
|
||||
protected ConfigurableApplicationContext createContext() {
|
||||
return new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/beanConfigurerTests.xml");
|
||||
}
|
||||
|
||||
public void testInjectionAfterRefresh() {
|
||||
context.refresh();
|
||||
ShouldBeConfiguredBySpring myObject = new ShouldBeConfiguredBySpring();
|
||||
assertEquals("Rod", myObject.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?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:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$WireArbitraryExistingPojo"
|
||||
factory-method="aspectOf"/>
|
||||
|
||||
<bean id="beanOne" class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$ShouldBeConfiguredBySpring"
|
||||
lazy-init="true">
|
||||
<property name="name" value="Rod"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$ShouldBeConfiguredBySpringUsingTypeNameAsBeanName"
|
||||
lazy-init="true">
|
||||
<property name="name" value="Rob"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$SubBean"
|
||||
lazy-init="true">
|
||||
<property name="name" value="Ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$SubBeanPreConstruction"
|
||||
lazy-init="true">
|
||||
<property name="name" value="Ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$SubSerializableBean"
|
||||
lazy-init="true">
|
||||
<property name="name" value="Ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean id="circular" class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$CircularFactoryBean"
|
||||
autowire-candidate="false"/>
|
||||
|
||||
<!-- Used as a target for autowiring by type -->
|
||||
<bean id="ramnivas" class="org.springframework.beans.TestBean" depends-on="circular">
|
||||
<property name="name" value="Ramnivas"/>
|
||||
<property name="spouse" ref="circular"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$ArbitraryExistingPojo">
|
||||
<property name="friend" ref="ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$PreConstructionConfiguredBean">
|
||||
<property name="name" value="ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$PostConstructionConfiguredBean">
|
||||
<property name="name" value="ramnivas"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$GenericParameterConfigurableBean" scope="prototype">
|
||||
<property name="testService" ref="testService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="testService" class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$TestService"/>
|
||||
<bean id="paymentService" class="org.springframework.beans.factory.aspectj.AbstractBeanConfigurerTests$PaymentService"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<context:spring-configured/>
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<import resource="beanConfigurerTests-beans.xml"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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:context="http://www.springframework.org/schema/context"
|
||||
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
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<context:spring-configured/>
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
</beans>
|
||||
596
spring-aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java
vendored
Normal file
596
spring-aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.springframework.cache.aspectj;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.config.AnnotatedClassCacheableService;
|
||||
import org.springframework.cache.config.CacheableService;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Abstract annotation test (containing several reusable methods).
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public abstract class AbstractAnnotationTest {
|
||||
|
||||
protected ApplicationContext ctx;
|
||||
|
||||
protected CacheableService<?> cs;
|
||||
|
||||
protected CacheableService<?> ccs;
|
||||
|
||||
protected CacheManager cm;
|
||||
|
||||
/** @return a refreshed application context */
|
||||
protected abstract ApplicationContext getApplicationContext();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
ctx = getApplicationContext();
|
||||
cs = ctx.getBean("service", CacheableService.class);
|
||||
ccs = ctx.getBean("classService", CacheableService.class);
|
||||
cm = ctx.getBean(CacheManager.class);
|
||||
Collection<String> cn = cm.getCacheNames();
|
||||
assertTrue(cn.contains("default"));
|
||||
}
|
||||
|
||||
public void testCacheable(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
Object r3 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
assertSame(r1, r3);
|
||||
}
|
||||
|
||||
public void testEvict(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
service.invalidate(o1);
|
||||
Object r3 = service.cache(o1);
|
||||
Object r4 = service.cache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testEvictEarly(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
try {
|
||||
service.evictEarly(o1);
|
||||
} catch (RuntimeException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
Object r3 = service.cache(o1);
|
||||
Object r4 = service.cache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testEvictException(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
try {
|
||||
service.evictWithException(o1);
|
||||
} catch (RuntimeException ex) {
|
||||
// expected
|
||||
}
|
||||
// exception occurred, eviction skipped, data should still be in the cache
|
||||
Object r3 = service.cache(o1);
|
||||
assertSame(r1, r3);
|
||||
}
|
||||
|
||||
public void testEvictWKey(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
service.evict(o1, null);
|
||||
Object r3 = service.cache(o1);
|
||||
Object r4 = service.cache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testEvictWKeyEarly(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
|
||||
try {
|
||||
service.invalidateEarly(o1, null);
|
||||
} catch (Exception ex) {
|
||||
// expected
|
||||
}
|
||||
Object r3 = service.cache(o1);
|
||||
Object r4 = service.cache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testEvictAll(CacheableService<?> service) throws Exception {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.cache(o1);
|
||||
Object r2 = service.cache(o1);
|
||||
|
||||
Object o2 = new Object();
|
||||
Object r10 = service.cache(o2);
|
||||
|
||||
assertSame(r1, r2);
|
||||
assertNotSame(r1, r10);
|
||||
service.evictAll(new Object());
|
||||
Cache cache = cm.getCache("default");
|
||||
assertNull(cache.get(o1));
|
||||
assertNull(cache.get(o2));
|
||||
|
||||
Object r3 = service.cache(o1);
|
||||
Object r4 = service.cache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testConditionalExpression(CacheableService<?> service) throws Exception {
|
||||
Object r1 = service.conditional(4);
|
||||
Object r2 = service.conditional(4);
|
||||
|
||||
assertNotSame(r1, r2);
|
||||
|
||||
Object r3 = service.conditional(3);
|
||||
Object r4 = service.conditional(3);
|
||||
|
||||
assertSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testKeyExpression(CacheableService<?> service) throws Exception {
|
||||
Object r1 = service.key(5, 1);
|
||||
Object r2 = service.key(5, 2);
|
||||
|
||||
assertSame(r1, r2);
|
||||
|
||||
Object r3 = service.key(1, 5);
|
||||
Object r4 = service.key(2, 5);
|
||||
|
||||
assertNotSame(r3, r4);
|
||||
}
|
||||
|
||||
public void testNullValue(CacheableService<?> service) throws Exception {
|
||||
Object key = new Object();
|
||||
assertNull(service.nullValue(key));
|
||||
int nr = service.nullInvocations().intValue();
|
||||
assertNull(service.nullValue(key));
|
||||
assertEquals(nr, service.nullInvocations().intValue());
|
||||
assertNull(service.nullValue(new Object()));
|
||||
assertEquals(nr + 1, service.nullInvocations().intValue());
|
||||
}
|
||||
|
||||
public void testMethodName(CacheableService<?> service, String keyName) throws Exception {
|
||||
Object key = new Object();
|
||||
Object r1 = service.name(key);
|
||||
assertSame(r1, service.name(key));
|
||||
Cache cache = cm.getCache("default");
|
||||
// assert the method name is used
|
||||
assertNotNull(cache.get(keyName));
|
||||
}
|
||||
|
||||
public void testCheckedThrowable(CacheableService<?> service) throws Exception {
|
||||
String arg = UUID.randomUUID().toString();
|
||||
try {
|
||||
service.throwChecked(arg);
|
||||
fail("Excepted exception");
|
||||
} catch (Exception ex) {
|
||||
assertEquals(arg, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testUncheckedThrowable(CacheableService<?> service) throws Exception {
|
||||
try {
|
||||
service.throwUnchecked(Long.valueOf(1));
|
||||
fail("Excepted exception");
|
||||
} catch (RuntimeException ex) {
|
||||
assertTrue("Excepted different exception type and got " + ex.getClass(),
|
||||
ex instanceof UnsupportedOperationException);
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testNullArg(CacheableService<?> service) {
|
||||
Object r1 = service.cache(null);
|
||||
assertSame(r1, service.cache(null));
|
||||
}
|
||||
|
||||
public void testCacheUpdate(CacheableService<?> service) {
|
||||
Object o = new Object();
|
||||
Cache cache = cm.getCache("default");
|
||||
assertNull(cache.get(o));
|
||||
Object r1 = service.update(o);
|
||||
assertSame(r1, cache.get(o).get());
|
||||
|
||||
o = new Object();
|
||||
assertNull(cache.get(o));
|
||||
Object r2 = service.update(o);
|
||||
assertSame(r2, cache.get(o).get());
|
||||
}
|
||||
|
||||
public void testConditionalCacheUpdate(CacheableService<?> service) {
|
||||
Integer one = Integer.valueOf(1);
|
||||
Integer three = Integer.valueOf(3);
|
||||
|
||||
Cache cache = cm.getCache("default");
|
||||
assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString()));
|
||||
assertNull(cache.get(one));
|
||||
|
||||
assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString()));
|
||||
assertEquals(three, Integer.valueOf(cache.get(three).get().toString()));
|
||||
}
|
||||
|
||||
public void testMultiCache(CacheableService<?> service) {
|
||||
Object o1 = new Object();
|
||||
Object o2 = new Object();
|
||||
|
||||
Cache primary = cm.getCache("primary");
|
||||
Cache secondary = cm.getCache("secondary");
|
||||
|
||||
assertNull(primary.get(o1));
|
||||
assertNull(secondary.get(o1));
|
||||
Object r1 = service.multiCache(o1);
|
||||
assertSame(r1, primary.get(o1).get());
|
||||
assertSame(r1, secondary.get(o1).get());
|
||||
|
||||
Object r2 = service.multiCache(o1);
|
||||
Object r3 = service.multiCache(o1);
|
||||
|
||||
assertSame(r1, r2);
|
||||
assertSame(r1, r3);
|
||||
|
||||
assertNull(primary.get(o2));
|
||||
assertNull(secondary.get(o2));
|
||||
Object r4 = service.multiCache(o2);
|
||||
assertSame(r4, primary.get(o2).get());
|
||||
assertSame(r4, secondary.get(o2).get());
|
||||
}
|
||||
|
||||
public void testMultiEvict(CacheableService<?> service) {
|
||||
Object o1 = new Object();
|
||||
|
||||
Object r1 = service.multiCache(o1);
|
||||
Object r2 = service.multiCache(o1);
|
||||
|
||||
Cache primary = cm.getCache("primary");
|
||||
Cache secondary = cm.getCache("secondary");
|
||||
|
||||
assertSame(r1, r2);
|
||||
assertSame(r1, primary.get(o1).get());
|
||||
assertSame(r1, secondary.get(o1).get());
|
||||
|
||||
service.multiEvict(o1);
|
||||
assertNull(primary.get(o1));
|
||||
assertNull(secondary.get(o1));
|
||||
|
||||
Object r3 = service.multiCache(o1);
|
||||
Object r4 = service.multiCache(o1);
|
||||
assertNotSame(r1, r3);
|
||||
assertSame(r3, r4);
|
||||
|
||||
assertSame(r3, primary.get(o1).get());
|
||||
assertSame(r4, secondary.get(o1).get());
|
||||
}
|
||||
|
||||
public void testMultiPut(CacheableService<?> service) {
|
||||
Object o = Integer.valueOf(1);
|
||||
|
||||
Cache primary = cm.getCache("primary");
|
||||
Cache secondary = cm.getCache("secondary");
|
||||
|
||||
assertNull(primary.get(o));
|
||||
assertNull(secondary.get(o));
|
||||
Object r1 = service.multiUpdate(o);
|
||||
assertSame(r1, primary.get(o).get());
|
||||
assertSame(r1, secondary.get(o).get());
|
||||
|
||||
o = Integer.valueOf(2);
|
||||
assertNull(primary.get(o));
|
||||
assertNull(secondary.get(o));
|
||||
Object r2 = service.multiUpdate(o);
|
||||
assertSame(r2, primary.get(o).get());
|
||||
assertSame(r2, secondary.get(o).get());
|
||||
}
|
||||
|
||||
public void testMultiCacheAndEvict(CacheableService<?> service) {
|
||||
String methodName = "multiCacheAndEvict";
|
||||
|
||||
Cache primary = cm.getCache("primary");
|
||||
Cache secondary = cm.getCache("secondary");
|
||||
Object key = Integer.valueOf(1);
|
||||
|
||||
secondary.put(key, key);
|
||||
|
||||
assertNull(secondary.get(methodName));
|
||||
assertSame(key, secondary.get(key).get());
|
||||
|
||||
Object r1 = service.multiCacheAndEvict(key);
|
||||
assertSame(r1, service.multiCacheAndEvict(key));
|
||||
|
||||
// assert the method name is used
|
||||
assertSame(r1, primary.get(methodName).get());
|
||||
assertNull(secondary.get(methodName));
|
||||
assertNull(secondary.get(key));
|
||||
}
|
||||
|
||||
public void testMultiConditionalCacheAndEvict(CacheableService<?> service) {
|
||||
Cache primary = cm.getCache("primary");
|
||||
Cache secondary = cm.getCache("secondary");
|
||||
Object key = Integer.valueOf(1);
|
||||
|
||||
secondary.put(key, key);
|
||||
|
||||
assertNull(primary.get(key));
|
||||
assertSame(key, secondary.get(key).get());
|
||||
|
||||
Object r1 = service.multiConditionalCacheAndEvict(key);
|
||||
Object r3 = service.multiConditionalCacheAndEvict(key);
|
||||
|
||||
assertTrue(!r1.equals(r3));
|
||||
assertNull(primary.get(key));
|
||||
|
||||
Object key2 = Integer.valueOf(3);
|
||||
Object r2 = service.multiConditionalCacheAndEvict(key2);
|
||||
assertSame(r2, service.multiConditionalCacheAndEvict(key2));
|
||||
|
||||
// assert the method name is used
|
||||
assertSame(r2, primary.get(key2).get());
|
||||
assertNull(secondary.get(key2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheable() throws Exception {
|
||||
testCacheable(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidate() throws Exception {
|
||||
testEvict(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEarlyInvalidate() throws Exception {
|
||||
testEvictEarly(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvictWithException() throws Exception {
|
||||
testEvictException(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvictAll() throws Exception {
|
||||
testEvictAll(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidateWithKey() throws Exception {
|
||||
testEvictWKey(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEarlyInvalidateWithKey() throws Exception {
|
||||
testEvictWKeyEarly(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionalExpression() throws Exception {
|
||||
testConditionalExpression(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyExpression() throws Exception {
|
||||
testKeyExpression(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassCacheCacheable() throws Exception {
|
||||
testCacheable(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassCacheInvalidate() throws Exception {
|
||||
testEvict(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassEarlyInvalidate() throws Exception {
|
||||
testEvictEarly(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassEvictAll() throws Exception {
|
||||
testEvictAll(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassEvictWithException() throws Exception {
|
||||
testEvictException(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassCacheInvalidateWKey() throws Exception {
|
||||
testEvictWKey(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassEarlyInvalidateWithKey() throws Exception {
|
||||
testEvictWKeyEarly(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullValue() throws Exception {
|
||||
testNullValue(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassNullValue() throws Exception {
|
||||
Object key = new Object();
|
||||
assertNull(ccs.nullValue(key));
|
||||
int nr = ccs.nullInvocations().intValue();
|
||||
assertNull(ccs.nullValue(key));
|
||||
assertEquals(nr, ccs.nullInvocations().intValue());
|
||||
assertNull(ccs.nullValue(new Object()));
|
||||
// the check method is also cached
|
||||
assertEquals(nr, ccs.nullInvocations().intValue());
|
||||
assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodName() throws Exception {
|
||||
testMethodName(cs, "name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMethodName() throws Exception {
|
||||
testMethodName(ccs, "namedefault");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullArg() throws Exception {
|
||||
testNullArg(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassNullArg() throws Exception {
|
||||
testNullArg(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckedException() throws Exception {
|
||||
testCheckedThrowable(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassCheckedException() throws Exception {
|
||||
testCheckedThrowable(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUncheckedException() throws Exception {
|
||||
testUncheckedThrowable(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassUncheckedException() throws Exception {
|
||||
testUncheckedThrowable(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
testCacheUpdate(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassUpdate() {
|
||||
testCacheUpdate(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionalUpdate() {
|
||||
testConditionalCacheUpdate(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassConditionalUpdate() {
|
||||
testConditionalCacheUpdate(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiCache() {
|
||||
testMultiCache(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMultiCache() {
|
||||
testMultiCache(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiEvict() {
|
||||
testMultiEvict(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMultiEvict() {
|
||||
testMultiEvict(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPut() {
|
||||
testMultiPut(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMultiPut() {
|
||||
testMultiPut(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiCacheAndEvict() {
|
||||
testMultiCacheAndEvict(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMultiCacheAndEvict() {
|
||||
testMultiCacheAndEvict(ccs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiConditionalCacheAndEvict() {
|
||||
testMultiConditionalCacheAndEvict(cs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassMultiConditionalCacheAndEvict() {
|
||||
testMultiConditionalCacheAndEvict(ccs);
|
||||
}
|
||||
}
|
||||
41
spring-aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java
vendored
Normal file
41
spring-aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 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.cache.aspectj;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
||||
|
||||
|
||||
@Override
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStrategy() throws Exception {
|
||||
AnnotationCacheAspect aspect = ctx.getBean("org.springframework.cache.config.internalCacheAspect", AnnotationCacheAspect.class);
|
||||
Assert.assertSame(ctx.getBean("keyGenerator"), aspect.getKeyGenerator());
|
||||
}
|
||||
}
|
||||
138
spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java
vendored
Normal file
138
spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
@Cacheable("default")
|
||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
public static final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
public Object cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
public Object conditional(int field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Object key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
||||
public Object name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Object rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Object update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Object conditionalUpdate(Object arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Object nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Object multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Object multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Object multiUpdate(Object arg1) {
|
||||
return arg1;
|
||||
}
|
||||
}
|
||||
70
spring-aspects/src/test/java/org/springframework/cache/config/CacheableService.java
vendored
Normal file
70
spring-aspects/src/test/java/org/springframework/cache/config/CacheableService.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.springframework.cache.config;
|
||||
|
||||
/**
|
||||
* Basic service interface.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface CacheableService<T> {
|
||||
|
||||
T cache(Object arg1);
|
||||
|
||||
void invalidate(Object arg1);
|
||||
|
||||
void evictEarly(Object arg1);
|
||||
|
||||
void evictAll(Object arg1);
|
||||
|
||||
void evictWithException(Object arg1);
|
||||
|
||||
void evict(Object arg1, Object arg2);
|
||||
|
||||
void invalidateEarly(Object arg1, Object arg2);
|
||||
|
||||
T conditional(int field);
|
||||
|
||||
T key(Object arg1, Object arg2);
|
||||
|
||||
T name(Object arg1);
|
||||
|
||||
T nullValue(Object arg1);
|
||||
|
||||
T update(Object arg1);
|
||||
|
||||
T conditionalUpdate(Object arg2);
|
||||
|
||||
Number nullInvocations();
|
||||
|
||||
T rootVars(Object arg1);
|
||||
|
||||
T throwChecked(Object arg1) throws Exception;
|
||||
|
||||
T throwUnchecked(Object arg1);
|
||||
|
||||
// multi annotations
|
||||
T multiCache(Object arg1);
|
||||
|
||||
T multiEvict(Object arg1);
|
||||
|
||||
T multiCacheAndEvict(Object arg1);
|
||||
|
||||
T multiConditionalCacheAndEvict(Object arg1);
|
||||
|
||||
T multiUpdate(Object arg1);
|
||||
}
|
||||
144
spring-aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java
vendored
Normal file
144
spring-aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* Simple cacheable service
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DefaultCacheableService implements CacheableService<Long> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
private final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
@Cacheable("default")
|
||||
public Long cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", condition = "#classField == 3")
|
||||
public Long conditional(int classField) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Long key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName")
|
||||
public Long name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Long rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Long update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Long conditionalUpdate(Object arg) {
|
||||
return Long.valueOf(arg.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new Exception(arg1.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Long multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Long multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Long multiUpdate(Object arg1) {
|
||||
return Long.valueOf(arg1.toString());
|
||||
}
|
||||
}
|
||||
23
spring-aspects/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java
vendored
Normal file
23
spring-aspects/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 org.springframework.cache.config;
|
||||
|
||||
import org.springframework.cache.interceptor.DefaultKeyGenerator;
|
||||
|
||||
public class SomeKeyGenerator extends DefaultKeyGenerator {
|
||||
|
||||
}
|
||||
45
spring-aspects/src/test/java/org/springframework/cache/config/annotation-cache-aspectj.xml
vendored
Normal file
45
spring-aspects/src/test/java/org/springframework/cache/config/annotation-cache-aspectj.xml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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:p="http://www.springframework.org/schema/p"
|
||||
xmlns:cache="http://www.springframework.org/schema/cache"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
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/cache http://www.springframework.org/schema/cache/spring-cache.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
|
||||
<!--
|
||||
<aop:config>
|
||||
<aop:advisor advice-ref="debugInterceptor" pointcut="execution(* *..CacheableService.*(..))" order="1"/>
|
||||
</aop:config>
|
||||
|
||||
<bean id="cacheAspect" class="org.springframework.cache.aspectj.AnnotationCacheAspect" factory-method="aspectOf">
|
||||
<property name="cacheManager" ref="cacheManager"/>
|
||||
<property name="cacheOperationSources" ref="annotationSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="annotationSource" class="org.springframework.cache.annotation.AnnotationCacheOperationSource"/>
|
||||
-->
|
||||
|
||||
<cache:annotation-driven mode="aspectj" key-generator="keyGenerator"/>
|
||||
|
||||
<bean id="keyGenerator" class="org.springframework.cache.config.SomeKeyGenerator" />
|
||||
|
||||
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||
<property name="caches">
|
||||
<set>
|
||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="primary"/>
|
||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="secondary"/>
|
||||
</set>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>
|
||||
|
||||
<bean id="service" class="org.springframework.cache.config.DefaultCacheableService"/>
|
||||
<bean id="classService" class="org.springframework.cache.config.AnnotatedClassCacheableService"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.mock.staticmock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test for static entity mocking framework.
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@MockStaticEntityMethods
|
||||
@RunWith(JUnit4.class)
|
||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||
|
||||
@Test
|
||||
public void testNoArgIntReturn() {
|
||||
int expectedCount = 13;
|
||||
Person.countPeople();
|
||||
expectReturn(expectedCount);
|
||||
playback();
|
||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||
}
|
||||
|
||||
@Test(expected=PersistenceException.class)
|
||||
public void testNoArgThrows() {
|
||||
Person.countPeople();
|
||||
expectThrow(new PersistenceException());
|
||||
playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodMatches() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongSeriesOfCalls() {
|
||||
long id1 = 13;
|
||||
long id2 = 24;
|
||||
Person found1 = new Person();
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person found2 = new Person();
|
||||
Person.findPerson(id2);
|
||||
expectReturn(found2);
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person.countPeople();
|
||||
expectReturn(0);
|
||||
playback();
|
||||
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(0, Person.countPeople());
|
||||
}
|
||||
|
||||
// Note delegation is used when tests are invalid and should fail, as otherwise
|
||||
// the failure will occur on the verify() method in the aspect after
|
||||
// this method returns, failing the test case
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
try {
|
||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||
}
|
||||
|
||||
private void called(Person found, long id) {
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrant() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
called(found, id);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testRejectUnexpectedCall() {
|
||||
new Delegate().rejectUnexpectedCall();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testFailTooFewCalls() {
|
||||
new Delegate().failTooFewCalls();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
// Test that verification check doesn't blow up if no replay() call happened
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverReplay() {
|
||||
new Delegate().doesntEverReplay();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverSetReturn() {
|
||||
new Delegate().doesntEverSetReturn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.mock.staticmock;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||
|
||||
//Used because verification failures occur after method returns,
|
||||
//so we can't test for them in the test case itself
|
||||
@MockStaticEntityMethods
|
||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||
public class Delegate {
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failTooFewCalls() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverReplay() {
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverSetReturn() {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectUnexpectedCall() {
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test(expected=RemoteException.class)
|
||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
// No calls to allow verification failure
|
||||
throw new RemoteException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.mock.staticmock;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.mock.staticmock;
|
||||
|
||||
privileged aspect Person_Roo_Entity {
|
||||
|
||||
@javax.persistence.PersistenceContext
|
||||
transient javax.persistence.EntityManager Person.entityManager;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||
@javax.persistence.Column(name = "id")
|
||||
private java.lang.Long Person.id;
|
||||
|
||||
@javax.persistence.Version
|
||||
@javax.persistence.Column(name = "version")
|
||||
private java.lang.Integer Person.version;
|
||||
|
||||
public java.lang.Long Person.getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void Person.setId(java.lang.Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public java.lang.Integer Person.getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void Person.setVersion(java.lang.Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.persist() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.persist(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.remove() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.remove(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.flush() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.merge() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
Person merged = this.entityManager.merge(this);
|
||||
this.entityManager.flush();
|
||||
this.id = merged.getId();
|
||||
}
|
||||
|
||||
public static long Person.countPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findAllPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").getResultList();
|
||||
}
|
||||
|
||||
public static Person Person.findPerson(java.lang.Long id) {
|
||||
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person");
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.find(Person.class, id);
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class AnnotationAsyncExecutionAspectTests {
|
||||
|
||||
private static final long WAIT_TIME = 1000; //milli seconds
|
||||
|
||||
private CountingExecutor executor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executor = new CountingExecutor();
|
||||
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodGetsRoutedAsynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.incrementAsync();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncMethodGetsRoutedSynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.increment();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
obj.increment();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
int returnValue = obj.return5();
|
||||
assertEquals(5, returnValue);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
||||
int submitStartCounter;
|
||||
int submitCompleteCounter;
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
submitStartCounter++;
|
||||
Future<T> future = super.submit(task);
|
||||
submitCompleteCounter++;
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
public synchronized void waitForCompletion() {
|
||||
try {
|
||||
wait(WAIT_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ClassWithoutAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
@Async public void incrementAsync() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
@Async public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
|
||||
// It should be an error to attach @Async to a method that returns a non-void
|
||||
// or non-Future.
|
||||
// We need to keep this commented out, otherwise there will be a compile-time error.
|
||||
// Please uncomment and re-comment this periodically to check that the compiler
|
||||
// produces an error message due to the 'declare error' statement
|
||||
// in AnnotationAsyncExecutionAspect
|
||||
// @Async public int getInt() {
|
||||
// return 0;
|
||||
// }
|
||||
}
|
||||
|
||||
@Async
|
||||
static class ClassWithAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
||||
public int return5() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.transaction;
|
||||
|
||||
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class CallCountingTransactionManager extends AbstractPlatformTransactionManager {
|
||||
|
||||
public TransactionDefinition lastDefinition;
|
||||
public int begun;
|
||||
public int commits;
|
||||
public int rollbacks;
|
||||
public int inflight;
|
||||
|
||||
protected Object doGetTransaction() {
|
||||
return new Object();
|
||||
}
|
||||
|
||||
protected void doBegin(Object transaction, TransactionDefinition definition) {
|
||||
this.lastDefinition = definition;
|
||||
++begun;
|
||||
++inflight;
|
||||
}
|
||||
|
||||
protected void doCommit(DefaultTransactionStatus status) {
|
||||
++commits;
|
||||
--inflight;
|
||||
}
|
||||
|
||||
protected void doRollback(DefaultTransactionStatus status) {
|
||||
++rollbacks;
|
||||
--inflight;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
begun = commits = rollbacks = inflight = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithPrivateAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void doInTransaction() {}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithProtectedAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected void doInTransaction() {}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public interface ITransactional {
|
||||
|
||||
Object echo(Throwable t) throws Throwable;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class MethodAnnotationOnClassWithNoInterface {
|
||||
|
||||
@Transactional(rollbackFor=InterruptedException.class)
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void noTransactionAttribute() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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="transactionManager" class="org.springframework.transaction.CallCountingTransactionManager"/>
|
||||
|
||||
<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.transaction.aspectj.TransactionalAnnotationOnlyOnClassWithNoInterface"/>
|
||||
|
||||
<bean class="org.springframework.transaction.aspectj.ClassWithProtectedAnnotatedMember"/>
|
||||
|
||||
<bean class="org.springframework.transaction.aspectj.ClassWithPrivateAnnotatedMember"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.springframework.transaction.CallCountingTransactionManager;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttribute;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private TransactionAspectSupport transactionAspect;
|
||||
|
||||
private CallCountingTransactionManager txManager;
|
||||
|
||||
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
|
||||
|
||||
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
|
||||
|
||||
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
|
||||
|
||||
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
|
||||
|
||||
|
||||
public void setAnnotationOnlyOnClassWithNoInterface(
|
||||
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
|
||||
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedProtectedMethod = aBean;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedPrivateMethod = aBean;
|
||||
}
|
||||
|
||||
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
|
||||
this.transactionAspect = transactionAspect;
|
||||
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
|
||||
}
|
||||
|
||||
public TransactionAspectSupport getTransactionAspect() {
|
||||
return this.transactionAspect;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getConfigPath() {
|
||||
return "TransactionAspectTests-context.xml";
|
||||
}
|
||||
|
||||
|
||||
public void testCommitOnAnnotatedClass() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedProtectedMethod.doInTransaction();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedPrivateMethod.doSomething();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0,txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
|
||||
assertEquals(0,txManager.begun);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
methodAnnotationOnly.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
|
||||
public static class NotTransactional {
|
||||
public void noop() {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNotTransactional() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
new NotTransactional().noop();
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
||||
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class ImplementsAnnotatedInterface implements ITransactional {
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new Exception());
|
||||
// }
|
||||
// }, false);
|
||||
|
||||
final Exception ex = new Exception();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(ex);
|
||||
}
|
||||
}, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: resolution does not occur. Thus we can't make a class transactional if
|
||||
* it implements a transactionally annotated interface. This behaviour could only
|
||||
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
|
||||
* @throws SecurityException
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
|
||||
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
||||
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
|
||||
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
|
||||
assertNull(ta);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
|
||||
// }
|
||||
// }, true);
|
||||
|
||||
final Exception rollbackProvokingException = new RuntimeException();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
|
||||
}
|
||||
}, rollbackProvokingException);
|
||||
}
|
||||
|
||||
|
||||
protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
catch (Throwable caught) {
|
||||
if (caught instanceof AssertionFailedError) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rollback) {
|
||||
assertEquals(1, txManager.rollbacks);
|
||||
}
|
||||
assertEquals(1, txManager.begun);
|
||||
}
|
||||
|
||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (expected == null) {
|
||||
fail("Expected " + expected);
|
||||
}
|
||||
assertSame(expected, t);
|
||||
}
|
||||
finally {
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private interface TransactionOperationCallback {
|
||||
|
||||
Object performTransactionalOperation() throws Throwable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public class TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void nonTransactionalMethod() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user