spring3는 ClassPathBeanDefinitionScanner을 제공해서 spring container에 bean을 생성할 수 있도록 도와준다.



ClassPathBeanDefinitionScanner scanner = new PlayClassPathBeanDefinitionScanner(applicationContext);

String scanBasePackage = ..

scanner.scan(scanBasePackage.split(","));



예를 들어, play1 playframework의 spring module은 ClassPathBeanDefinitionScanner을 사용한다. 

https://github.com/pepite/Play--framework-Spring-module/blob/master/src/play/modules/spring/SpringPlugin.java

그런데.. play1 playframework의 spinrg module을 spring4로 변경하면 동작이 안된다. 

spring3과 spring4의 차이를 살펴본다.


문제가 되는 부분을 설명한다. 내부에 ConfigurationClassParser 클래스의 asSourceClass 메소드가 변경되었다.
spring3 코드와 달리 spring4에서는 외부에서 읽힐 때 현재 classload에서 읽지 목한다면 ClassNotFoundException이 생긴다.(안전함을 더 중요하게 여기고 수정되었다)

<spring 3>


/**
* Factory method to obtain a {@link SourceClass} from a {@link Class}.
*/
public SourceClass asSourceClass(Class<?> classType) throws IOException {
try {
// Sanity test that we can read annotations, if not fall back to ASM
classType.getAnnotations();
return new SourceClass(classType);
}
catch (Throwable ex) {
// Enforce ASM via class name resolution
return asSourceClass(classType.getName());
}
}




<spring 4>


https://github.com/spring-projects/spring-framework/blob/5b98a54c9b9f8c2f4332734ee23cd483b7df0d22/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java#L659


/**

 * Factory method to obtain a {@link SourceClass} from a class name.
 */
public SourceClass asSourceClass(String className) throws IOException {
if (className.startsWith("java")) {
// Never use ASM for core java types
try {
return new SourceClass(this.resourceLoader.getClassLoader().loadClass(className));
}
catch (ClassNotFoundException ex) {
throw new NestedIOException("Failed to load class [" + className + "]", ex);
}
}
return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
}


참고

https://jira.spring.io/browse/SPR-15245



Posted by '김용환'
,