不知道大家想过没有,我们使用mybatis的时候只要写接口和配置上一个sql语句就可以了,单从代码的角度来看,这是不合理的。

所以我们通常在service里面注入的mapper它其实是一个代理对象

回到本人上一篇博客spring给容器中注入组件的几种方式

1.包扫描+组件注解标签注解

这种方式一般适用于自己写的类,动态代理的类无法添加(就算你自己动态生成的类上有注解标签,spring也无法扫描)

2.@bean

这种方式适用于加入第三方库中的类

这种方式真的可以吗?仔细想想,这种方式只能一个一个添加,像mybatis有这么多的mapper我们一个一个的加就麻烦了

3.@improt

这种方式的简单用法是肯定不行的,因为是动态生成的类,你无法再类写@improt(xxxx.class)

4.使用spring提供的factoryBean

写一个类实现factoryBean接口,重写getObject方法

这种方式显然和@bean有一样的缺陷,返回值只能有一个,还是要一个一个添加

======================================主文来了=======================================

解决办法就是@improt>>>>实现ImportBeanDefinitionRegistrar接口+.使用spring提供的factoryBean

public class MyMapperFactoryBean implements FactoryBean{

    @Autowired
private SqlSessionFactoryBean sqlSessionFactoryBean;
private Class aClass; public void setaClass(Class aClass) {
this.aClass = aClass;
} public MyMapperFactoryBean(Class aClass) {
this.aClass = aClass;
}
//产生动态代理,需要产生代理的类型在构造方法传入
@Nullable
@Override
public Object getObject() throws Exception {
Class[] clazz=new Class[]{aClass};
Object obj = Proxy.newProxyInstance(this.getClass().getClassLoader(), clazz, new MapperInvocationHandler(sqlSessionFactoryBean));
return obj;
} @Nullable
@Override
public Class<?> getObjectType() {
return TestMapper.class;
}
}

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//注册MyMapperFactoryBean
//为什么不用其他方式注册MyMapperFactoryBean呢 因为这里是代码形式,可以循环,产生多个
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(MyMapperFactoryBean.class);
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
//传入MyMapperFactoryBean的构造方法类型 你要代理那个类就传入那个类
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.tjx.mapper.TestMapper");
//注册
beanDefinitionRegistry.registerBeanDefinition("mapper",beanDefinition);
}
}

=============================这样就OK了,讲讲思路==================================

1.循环注册

2.FactoryBean这个类被我们注册到了容器中,所有可以使用spring容器中的组件  如sqlsessionFactoryBean

    //这里因为我们没有使用mybatis为我们生成动态代理 所以这里不能使用mybatis的功能
//但是mybatis官方他自己把sqlSessionFactoryBean传入进来就是能用的 (这里有点绕,因为我不可能去把mybatis的底层实现自己写一遍)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String str=method.getAnnotation(Select.class).value()[0]; //获取方法注解上的sql语句
System.out.println("查询数据库"+str);
List<Test> lists=new ArrayList<>();
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
int count=0;
try {
con=DBHelper.getCon();
ps=con.prepareStatement(str);
rs=ps.executeQuery();
while (rs.next()){
Test test=new Test();
int id = rs.getInt("id");
String name = rs.getString("name");
test.setId(id);
test.setName(name);
lists.add(test);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
DBHelper.myClose(con, ps, rs);
}
// SqlSessionFactory object = sqlSessionFactoryBean.getObject();
// SqlSession sqlSession = object.openSession();
// System.out.println(sqlSession);
// List<Test> objects = sqlSession.selectList(str);
return lists;
}

最新文章

  1. 手动建库时一个小错误:ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
  2. SQL 分页
  3. NGUI 界面自适应
  4. Xamarin.Android开发实践(十五)
  5. Nullsoft教程 NSIS初学者图文教程一
  6. Spark RDD概念学习系列之RDD的5大特点(五)
  7. PHP Warning: date(): It is not safe to rely on the system&#39;s timezone settings.
  8. ant design 树形组件怎么使用
  9. 安装robotframework时提示权限受限
  10. Sliding Window Maximum
  11. switch语句:适用于一个条件有多个分支的情况---分支语句
  12. Jquery EasyUI tabs处理
  13. NYOJ-1036 非洲小孩(贪心)
  14. spring mvc4使用及json 日期转换解决方案
  15. 【java提高】---ArrayList源码
  16. MHA 安装与简单使用
  17. 5.2、Android Studio截图
  18. jsonp学习
  19. WPF 通过透明度遮罩和变换制作倒影效果
  20. HTML5+CSS3-学习总结

热门文章

  1. (六)mybatis-spring集成完整版
  2. 4.2英寸的iPhone SE2就要来了!但你还会买单吗?
  3. res文件夹及xml资源文件详解
  4. Python建立web静态服务器
  5. Problem 43 // Project Euler
  6. 牛奶别乱喝6种最好最差牛奶PK
  7. C:指针习题
  8. JavaScript中如何给按钮设置隐藏与显示属性
  9. JMeter-临界部分控制器
  10. 《前端之路》--- 重温 Egg.js