核心在@MapperScan这个注解,ImportBeanDefinitionRegistrar这是一个bfpp,spring启动的时候一定会执行,这个类主要是用来将自定义的beandefinition注入到容器中,
1.会先获取@MapperScan里面value的值
2.然后遍历value路径下所有接口,
3.对于上一步扫描得到的beandefiniton,然后给bd加入
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName()); beanDefinition.setBeanClassName(MapperFactoryBean.class.getName());
这两行,注意所有的class都是FactoryBean类型,有多少个mapper就有多少个factorybean,
4.对于factorybean,会有一个构造方法
public ZhouyuFactoryBean(Class mapperInterface) { this.mapperInterface = mapperInterface; }
主要是把接口注入到构造方法里面
5.spring生命周期会调用getObject()最后注入到spring容器中,注意这里是一个代理对象
@Override public Object getObject() throws Exception { return sqlSession.getMapper(mapperInterface); }
6.那么sqlSession的值怎么来的?,通过@Autowired注入
@Autowired public void setSqlSession(SqlSessionFactory sqlSessionFactory) { sqlSessionFactory.getConfiguration().addMapper(mapperInterface); this.sqlSession = sqlSessionFactory.openSession(); }
7.sqlSessionFactory如何来的?需要用户自己来配置
public SqlSessionFactory sqlSessionFactory() throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; }
后者注解形式注入
@Bean public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); return sessionFactoryBean.getObject(); }
@Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/bzaaf?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"); dataSource.setUsername("root"); dataSource.setPassword("root1122"); return dataSource; }