spring整合mybatis简单说明
小小的疑问
有没有好奇,在使用spring 整合mybatis的时候,我们直接在service层注入mapper,mapper只是一个接口,但是就可以直接使用了。为什么可以直接用呢,spring是不能直接注入接口,带着这个疑问,我们往下面分析。
动态代理
我们知道,mybatis 其实是通过动态代理实现的,本文只是简单说明一下,myabtis的具体实现就不在阐述了。我们先看一下动态代理的内容。
先定义一个接口
public interface TestMapper {
void testZ();
}
定义一个代理类
public class TestMapperProxy implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy is "+proxy.getClass());
System.out.println("method name is "+method.getName());
return null;
}
}
测试方法
@Test
public void test(){
TestMapper testMapper=(TestMapper) Proxy.newProxyInstance(TestMapper.class.getClassLoader(),
new Class[] { TestMapper.class },
new TestMapperProxy());
testMapper.testZ();
}
输出结果为
proxy is class com.sun.proxy.$Proxy4
method name is testZ
通过以上代码,我们就可以用代理实现一个没有实现的接口的调用,spring 整合mybatis 其实也是这种方法,我们只要把这种代理对象放到spring容器中就行。那么,怎么放呢?
FactoryBean
我们知道spring有FactoryBean和BeanFactory,网上也有很多这2种比较的文章,我简单说一下把:
- BeanFactory就是工厂模式,里面存储了我们的一些对象。
- FactoryBean 就是一个bean,spring帮助可以构造对象,但是有时候我们需要重新定义这些对象的构造过程。
FactoryBean有2个重要的方法,一个是getObject(),另外一个是getObjectType()。
- getObject() 这个方法会返回一个对象,这个对象会被spring管理。
- getObjectType() 返回一个class类型,这个类型就是getObject()返回对象的class类型。
接下来我们看下代码:
@Component
public class TestMapperFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return Proxy.newProxyInstance(TestMapper.class.getClassLoader(),new Class[] { TestMapper.class },
new TestMapperProxy());
}
@Override
public Class<?> getObjectType() {
return TestMapper.class;
}
}
通过以上方法,我们就把类型为TestMapper的对象放到了spring容器中,我们就可以在别的类里面注入这个mapper了,是不是很简单。接下来看下整个的测试代码:
@RestController
@RequestMapping("/testProxy")
public class TestProxyController {
@Autowired
TestMapper testMapper;
@RequestMapping("/testMapper")
public String testMapper(){
testMapper.testZ();
return "OK";
}
}
输出结果:
proxy is class com.sun.proxy.$Proxy78
method name is testZ
myabtis用的是MapperFactoryBean,ClassPathMapperScanner,大家有空可以去研究一下。
大功告成了,是不是很简单。
我们就是要用这个好奇心去看一些东西,学习一些东西,文章不足之处,希望大家多批评指正。