MyBatis-Spring的源代码里有这么一个类,它的代码如下
public class MapperScannerConfigurer implements BeanFactoryPostProcessor, InitializingBean {
private String basePackage;
private boolean addToConfig = true;
private SqlSessionFactory sqlSessionFactory;
private SqlSessionTemplate sqlSessionTemplate;
private Class<? extends Annotation> annotationClass;
private Class<?> markerInterface;
/** * Calls the parent search that will search and register all the candidates. Then the * registered objects are post processed to set them as MapperFactoryBeans */ @[author]Override[/author] protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
if (beanDefinitions.isEmpty()) { logger.warn("No MyBatis mapper was found in '" + MapperScannerConfigurer.this.basePackage + "' package. Please check your configuration."); } else { for (BeanDefinitionHolder holder : beanDefinitions) { GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
if (logger.isDebugEnabled()) { logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + definition.getBeanClassName() + "' mapperInterface"); }
// the mapper interface is the original class of the bean // but, the actual class of the bean is MapperFactoryBean definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName()); definition.setBeanClass(MapperFactoryBean.class);
definition.getPropertyValues().add("addToConfig", MapperScannerConfigurer.this.addToConfig);
if (MapperScannerConfigurer.this.sqlSessionFactory != null) { definition.getPropertyValues().add("sqlSessionFactory", MapperScannerConfigurer.this.sqlSessionFactory); }
if (MapperScannerConfigurer.this.sqlSessionTemplate != null) { definition.getPropertyValues().add("sqlSessionTemplate", MapperScannerConfigurer.this.sqlSessionTemplate); } } }
return beanDefinitions; }
@[author]Override[/author] protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { return (beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent()); }
@[author]Override[/author] protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException { if (super.checkCandidate(beanName, beanDefinition)) { return true; } else { logger.warn("Skipping MapperFactoryBean with name '" + beanName + "' and '" + beanDefinition.getBeanClassName() + "' mapperInterface" + ". Bean already defined with the same name!"); return false; } } }
}
|
这个类实现了Spring的两个接口,这两个接口代码如下
public interface InitializingBean { /** * Invoked by a BeanFactory after it has set all bean properties supplied * (and satisfied BeanFactoryAware and ApplicationContextAware). * <p>This method allows the bean instance to perform initialization only * possible when all bean properties have been set and to throw an * exception in the event of misconfiguration. * @throws Exception in the event of misconfiguration (such * as failure to set an essential property) or if initialization fails. */ void afterPropertiesSet() throws Exception;
}
|
public interface BeanFactoryPostProcessor {
/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
|
灵异事件发生:
在MapperScannerConfigurer类的方法中有logger.warn("No MyBatis mapper was found in '" + MapperScannerConfigurer.this.basePackage
+ "' package. Please check your configuration.");而在类属性里却没定义logger属性,程序运行时会抛出NoSuchFieldError:logger,跑出异常是肯定的,我在想MyBatis团队是怎么编译过这个类还打进Jar的呢?
修改Javac?
修改Spring源码?
这似乎都不太可能?你能想到吗?
[该贴被oojdon于2011-04-18 23:40修改过]