10.25
阿新 • • 發佈:2020-11-18
Mybatis整合Spring原始碼之前也分析過一次了,這次剛好腦袋靈光一閃,想出來一個在
SqlSessionDaoSupport.setSqlSessionFactory 是什麼時候呼叫的呢?
一 BeanDefinition
每一個mapper介面都會被掃描成一個BeanDefinition,這個BD開始會被強制轉成MapperFactoryBean型別,並
ClassPathMapperScanner.processBeanDefinitions
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) { GenericBeanDefinition definition;for (BeanDefinitionHolder holder : beanDefinitions) { 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.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); // issue #59 definition.setBeanClass(this.mapperFactoryBean.getClass()); definition.getPropertyValues().add("addToConfig", this.addToConfig); boolean explicitFactoryUsed = false; if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) { definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName)); explicitFactoryUsed = true;
在這個BD中,mapper的原始類加入到構造方法入參,sqlSessioinFactory放進了bd的屬性裡
二 生效時機
通過構造方法,Class<T> mapperInterface被注入了
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> { private Class<T> mapperInterface; private boolean addToConfig = true; public MapperFactoryBean() { //intentionally empty } public MapperFactoryBean(Class<T> mapperInterface) { this.mapperInterface = mapperInterface; }
sqlSessioinFactory的注入在對bean的初始化的第二步
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (hasInstAwareBpps || needsDepCheck) {//這部分是對@AutoWired或者@Resource進行注入的 PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } //走完了上面的程式碼後這個bean的@AutoWired或者@Resource的屬性就已經注入完了
applyPropertyValues(beanName, mbd, bw, pvs); //這個方法處理的是BeanDefinition裡的靜態屬性,也就是BeanDefinition裡已經寫好了的屬性
}
applyPropertyValues會對BD中的全部屬性進行處理,我看了下呼叫還有點複雜,不過底層應該還是通過Field的反射介面
這樣,我們就知道了sqlSessioinFactory是怎麼注入的了