Browse Source

fixed two build-breaking issues:

+ reverted ClassMetadataReadingVisitor to revision 794
+ eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests)


git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@814 50f2f4bb-b051-0410-bef5-90022cba6387
pull/1/head
Chris Beams 17 years ago
parent
commit
4776108767
  1. 143
      org.springframework.context/src/test/java/org/springframework/context/annotation/support/ConfigurationPostProcessorTests.java
  2. 46
      org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java

143
org.springframework.context/src/test/java/org/springframework/context/annotation/support/ConfigurationPostProcessorTests.java

@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation.support;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
import java.lang.reflect.Field;
import java.util.Vector;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
import org.springframework.util.ClassUtils;
/**
* Unit tests for {@link ConfigurationClassPostProcessor}.
*
* @author Chris Beams
*/
public class ConfigurationPostProcessorTests {
private static final String ORIG_CGLIB_TEST_CLASS = ConfigurationClassPostProcessor.CGLIB_TEST_CLASS;
private static final String BOGUS_CGLIB_TEST_CLASS = "a.bogus.class";
/**
* CGLIB is an optional dependency for Spring. If users attempt
* to use {@link Configuration} classes, they'll need it on the classpath;
* if Configuration classes are present in the bean factory and CGLIB
* is not present, an instructive exception should be thrown.
*/
@Test
public void testFailFastIfCglibNotPresent() {
@Configuration class Config { }
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("config", rootBeanDefinition(Config.class).getBeanDefinition());
ConfigurationClassPostProcessor cpp = new ConfigurationClassPostProcessor();
// temporarily set the cglib test class to something bogus
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = BOGUS_CGLIB_TEST_CLASS;
try {
cpp.postProcessBeanFactory(factory);
} catch (RuntimeException ex) {
assertTrue(ex.getMessage().contains("CGLIB is required to process @Configuration classes"));
} finally {
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = ORIG_CGLIB_TEST_CLASS;
}
}
/**
* In order to keep Spring's footprint as small as possible, CGLIB must
* not be required on the classpath unless the user is taking advantage
* of {@link Configuration} classes.
*
* This test will fail if any CGLIB classes are classloaded before the call
* to {@link ConfigurationClassPostProcessor#enhanceConfigurationClasses}
*/
@Test
public void testCglibClassesAreLoadedJustInTimeForEnhancement() throws Exception {
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
Field classesField = ClassLoader.class.getDeclaredField("classes");
classesField.setAccessible(true);
// first, remove any CGLIB classes that may have been loaded by other tests
@SuppressWarnings("unchecked")
Vector<Class<?>> classes = (Vector<Class<?>>) classesField.get(classLoader);
Vector<Class<?>> cglibClassesAlreadyLoaded = new Vector<Class<?>>();
for(Class<?> loadedClass : classes)
if(loadedClass.getName().startsWith("net.sf.cglib"))
cglibClassesAlreadyLoaded.add(loadedClass);
for(Class<?> cglibClass : cglibClassesAlreadyLoaded)
classes.remove(cglibClass);
// now, execute a scenario where everything except enhancement occurs
// -- no CGLIB classes should get loaded!
testFailFastIfCglibNotPresent();
// test to ensure that indeed no CGLIB classes have been loaded
for(Class<?> loadedClass : classes)
if(loadedClass.getName().startsWith("net.sf.cglib"))
fail("CGLIB class should not have been eagerly loaded: " + loadedClass.getName());
}
/**
* Enhanced {@link Configuration} classes are only necessary for respecting
* certain bean semantics, like singleton-scoping, scoped proxies, etc.
*
* Technically, {@link ConfigurationClassPostProcessor} could fail to enhance the
* registered Configuration classes and many use cases would still work.
* Certain cases, however, like inter-bean singleton references would not.
* We test for such a case below, and in doing so prove that enhancement is
* working.
*/
@Test
public void testEnhancementIsPresentBecauseSingletonSemanticsAreRespected() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("config",
rootBeanDefinition(SingletonBeanConfig.class).getBeanDefinition());
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
Foo foo = (Foo) beanFactory.getBean("foo");
Bar bar = (Bar) beanFactory.getBean("bar");
assertThat(foo, sameInstance(bar.foo));
}
@Configuration
static class SingletonBeanConfig {
public @Bean Foo foo() {
return new Foo();
}
public @Bean Bar bar() {
return new Bar(foo());
}
}
static class Foo { }
static class Bar {
final Foo foo;
public Bar(Foo foo) { this.foo = foo; }
}
}

46
org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java

@ -16,13 +16,9 @@ @@ -16,13 +16,9 @@
package org.springframework.core.type.classreading;
import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.Attribute;
import org.springframework.asm.ClassVisitor;
import org.springframework.asm.FieldVisitor;
import org.springframework.asm.MethodVisitor;
import org.springframework.asm.ClassAdapter;
import org.springframework.asm.Opcodes;
import org.springframework.asm.commons.EmptyVisitor;
import org.springframework.core.type.ClassMetadata;
import org.springframework.util.ClassUtils;
@ -37,7 +33,7 @@ import org.springframework.util.ClassUtils; @@ -37,7 +33,7 @@ import org.springframework.util.ClassUtils;
* @author Ramnivas Laddad
* @since 2.5
*/
class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
class ClassMetadataReadingVisitor extends ClassAdapter implements ClassMetadata {
private String className;
@ -53,7 +49,12 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata { @@ -53,7 +49,12 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
private String[] interfaces;
public ClassMetadataReadingVisitor()
{
super(new EmptyVisitor());
}
@Override
public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
this.className = ClassUtils.convertResourcePathToClassName(name);
this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
@ -67,10 +68,12 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata { @@ -67,10 +68,12 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
}
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (outerName != null && this.className.equals(ClassUtils.convertResourcePathToClassName(name))) {
this.enclosingClassName = ClassUtils.convertResourcePathToClassName(outerName);
@ -78,33 +81,6 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata { @@ -78,33 +81,6 @@ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata {
}
}
public void visitSource(String source, String debug) {
// no-op
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
// no-op
return null;
}
public void visitAttribute(Attribute attr) {
// no-op
}
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
// no-op
return null;
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// no-op
return null;
}
public void visitEnd() {
// no-op
}
public String getClassName() {
return this.className;

Loading…
Cancel
Save