[스프링 3.0 테스트 확장] 애노테이션 설정 기반 테스트 러너 만들기 4 - 일단 끝
* @author Keesun Baik(Whiteship)
* @author Seongyoon Kim(Is윤군)
*/
public class AnnotationContextLoader extends AbstractContextLoader {
private static final String JAVA_FILE_SUFFIX = ".java";
private static final String APP_CONFIG_FILE_PREFIX = "AppConfig";
@Override
public String getResourceSuffix() {
return APP_CONFIG_FILE_PREFIX + JAVA_FILE_SUFFIX;
}
@Override
protected String[] generateDefaultLocations(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
String suffix = getResourceSuffix();
Assert.hasText(suffix, "Resource suffix must not be empty");
return new String[] { clazz.getName() + suffix };
}
@Override
protected String[] modifyLocations(Class<?> clazz, String... locations) {
String[] modifiedLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
String path = locations[i];
if(path.endsWith("/"))
path = path.substring(0, path.length() - 1);
if (path.startsWith("/")) {
modifiedLocations[i] = ClassUtils.convertResourcePathToClassName(path.substring(1));
}
else if (!ResourcePatternUtils.isUrl(path)) {
modifiedLocations[i] = getClassName(clazz, path);
}
else {
throw new UnsupportedOperationException();
}
}
return modifiedLocations;
}
private String getClassName(Class clazz, String path) {
return ClassUtils.convertResourcePathToClassName(
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + "/" + path));
}
public final ConfigurableApplicationContext loadContext(String... locations) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
prepareContext(context);
customizeBeanFactory(context.getDefaultListableBeanFactory());
context.register(getAppConfigClasses(context.getClassLoader(), locations));
context.scan(getAppConfigPackages(context.getClassLoader(), locations));
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
context.refresh();
context.registerShutdownHook();
return context;
}
private String[] getAppConfigPackages(ClassLoader classLoader, String[] locations) {
List<String> packages = new ArrayList<String>();
for(String location : locations){
if(!location.contains(JAVA_FILE_SUFFIX))
packages.add(location);
}
return packages.toArray(new String[packages.size()]);
}
private Class<?>[] getAppConfigClasses(ClassLoader classLoader, String[] locations) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<Class<?>>();
for(String location : locations){
if(location.contains(JAVA_FILE_SUFFIX))
classes.add(ClassUtils.forName(location.replace(JAVA_FILE_SUFFIX, ""), classLoader));
}
return classes.toArray(new Class<?>[classes.size()]);
}
protected void prepareContext(GenericApplicationContext context) {
}
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
}
protected void customizeContext(GenericApplicationContext context) {
}
이걸 사용하시면 됩니다. 이제 스프링 이슈에 올려야지. 캬캬캬
스프링 레퍼런스 공부할 때 오타 찾아서 이슈 등록하던게 엊그제 같은데 이젠 코드도 기여할 수 있으려나..
코드를 보시면 아시겠지만, classpath:, file:, url: 등의 prefix 지원은 포기했습니다. 그래도..
1. 스프링 애노테이션 설정 파일만 가지고 쉽게 테스트 할 수 있으며
2. 스프링 애노테이션 설정 파일을 명시적으로 설정할 수 있으며
3. 임의의 패키지를 명시적으로 설정할 수 있습니다.
딱 제가 원하던 만큼이니 이정도면 저는 만족합니다. 이걸 스프링에서 고쳐서 넣어주던 말던~ 일단은 try.
ps: 같이 코딩해주고 상의해준 성윤군과, 스프링 러너와 로더 설정 방법 알려주신 사부님 썡큐!