Spring整合MyBatis
MyBatis通过generatorConfig.xml生成的XXXMapper接口,MyBatis会生成接口对应的bean,放到Spring容器中管理;MyBatis是生成一个代理对象,使用到了FactoryBean,放到了Spring容器中,容器中的bean可以注入到其他组件中
生成代理对象并将bean交给FactoryBean的过程: 1、直接将一个对象放到Spring容器中:beanFactory.registerSingleton("xxx", new Xxx()); 2、通过FactoryBean生成一个代理对象,context加载时XXXFactoryBean实际会生成一个代理对象 beanClass是:com.pl.processor.TestFactoryBean,实际生成的是XXXMapper的代理对象,调用代理对象的任何方法时都会执行一遍invoke()方法
@Component
public class TestFactoryBean implements FactoryBean {
private Class mapper;
public TestFactoryBean(Class input) {
this.mapper = input;
}
// OrderMapper ------->new TestFactoryBean(OrderMapper.class)------>OrderMapper的代理对象
// bean的name是testFactoryBean,生成的对象是代理对象UserMapper
@Override
public Object getObject() throws Exception {
Object o = Proxy.newProxyInstance(mapper.getClassLoader(), new Class[]{mapper}, new InvocationHandler() {
// 调用代理对象的方法时都会调用invoke
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName());
return null;
}
});
return o;
}
@Override
public Class<?> getObjectType() {
return mapper;
}
// 可以不实现,default方法,默认返回true
@Override
public boolean isSingleton() {
return true;
}
}
3、依赖FactoryBean,在生成Bean的前置阶段:Class解析BeanDefinition的时候,批量的生成多个代理类; 解决方案: ① 自定义BeanDefinitionRegister实现ImportBeanDefinitionRegistrar,在registerBeanDefinitions方法中注册新的BeanDefinition ② 将修改后的BeanDefinition然后导入到BeanFactory中的BeanDefinitionMap: ③ 将该动作引入到Bean初始化的方式: @Import(TestBeanDefinitionRegister.class)
public class TestBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
// ① beanDefinitionRegistry注册表
List<Class> mappers = new ArrayList<Class>();
mappers.add(UserMapper.class);
mappers.add(OrderMapper.class);
// ② 优化方式:新增一个Mapper之后如何处理?如何实现自动导入
for (Class mapper : mappers) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
// 设置BeanDefinition对应的beanClass,改Class专门用来生产代理对象
beanDefinition.setBeanClass(TestFactoryBean.class);
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(mapper);
beanDefinitionRegistry.registerBeanDefinition(mapper.getSimpleName(), beanDefinition);
}
}
}