不知道大家想过没有,我们使用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;
}

spring动态添加bean的更多相关文章

  1. Spring动态注册bean实现动态多数据源

    Spring动态注册bean实现动态多数据源 http://blog.csdn.net/littlechang/article/details/8071882

  2. spring动态修改bean

    spring动态修改bean @RequestMapping("ok") public Object test2(){ ApplicationContext application ...

  3. Spring动态添加定时任务

    Spring动态添加定时任务 一.背景 二.需求和实现思路 1.能够动态的添加一个定时任务. 2.能够取消定时任务的执行. 3.动态的修改任务执行的时间. 4.获取定时任务执行的异常 三.代码实现 四 ...

  4. spring 手动添加 bean 到容器,例子 :多数据源配置

    package com.thunisoft.spsjsb.config.db.decrypt; import com.alibaba.druid.pool.DruidDataSource; impor ...

  5. 《精通Spring4.X企业应用开发实战》读后感第五章(通过编码方式动态添加Bean)

  6. SpringBoot动态注入Bean

    目的: 在程序运行期间,动态添加Bean进入到Spring容器. 目前使用到的场景: 对当当网的ElasticJob进行封装,通过自定义注解@ElasticJob的方式开启分布式定时任务. 当所有的B ...

  7. 生产环境屏蔽swagger(动态组装bean)

    spring动态组装bean 背景介绍: 整合swagger时需要在生产环境中屏蔽掉swagger的地址,不能在生产环境使用 解决方案 使用动态profile在生产环境中不注入swagger的bean ...

  8. Spring Boot通过ImportBeanDefinitionRegistrar动态注入Bean

    在阅读Spring Boot源码时,看到Spring Boot中大量使用ImportBeanDefinitionRegistrar来实现Bean的动态注入.它是Spring中一个强大的扩展接口.本篇文 ...

  9. Spring动态代理及Spring Bean的生命周期

    数组添加值 public class DiTest { /** * 数组 */ private String [] arrays; /** * List:集合 */ private List<I ...

随机推荐

  1. Luogu_2061_[USACO07OPEN]城市的地平线City Horizon

    题目描述 Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the cit ...

  2. SSM框架三分钟搞定分页查询

    使用的国产第三方jar   pagehelper 里面的基本属性值 //当前页 private int pageNum; //每页的数量 private int pageSize; //当前页的数量 ...

  3. SWUST OJ 爬不出去的水井(0333)

    爬不出去的水井(0333) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 1069 Accepted: 150 Descriptio ...

  4. Introduction Of Gradient Descent

    不是一个机器学习算法 是一种基于搜索的优化方法 作用:最小化一个损失函数 梯度上升法:最大化一个效用函数 import matplotlib.pyplot as plt import numpy as ...

  5. MyEclipse下Spring+Hibernate整合

    目前,SSH(Struts+Spring+Hibernate)是Web开发的一种常用框架组合,Struts实现了MVC,Hibernate实现了关系对象映射,Spring实现了基于Bean的配置管理. ...

  6. GO - if判断,for循环,switch语句,数组的使用

    1.if - else if - else的使用 package main import "fmt" func main() { // 1.简单使用 var a=10 if a== ...

  7. 07.深入浅出 Spring Boot - 数据访问之Mybatis(附代码下载)

    MyBatis 在Spring Boot应用非常广,非常强大的一个半自动的ORM框架. 代码下载:https://github.com/Jackson0714/study-spring-boot.gi ...

  8. linux安装国产数据库(金仓数据库,达梦数据库,南大通用数据库)

    今天在公司做的任务是,在Linux的环境下安装三种数据库,结果一种数据库也没有安装好,首先遇到的问题是安装南大通用数据库遇到安装的第五步,就出现问题了,问题是Gbase SDK没有安装成功,以及Gba ...

  9. 基于abp框架的数据库种子数据初始化

    目录 基于abp框架的数据库种子数据初始化 1.背景 2.参照 3.解决方案 3.1 初始化数据 3.2 依赖注入方法容器里获取数据库上下文 3.3 封装创建初始化数据列表方法 3.4 数据库中没有的 ...

  10. 使用 Hexo 创建项目文档网站

    当我们发布一个开源项目的时候,最重要的事情之一就是要创建项目文档.对使用项目的用户来说,文档是非常有必要的,通常我们可以使用下面这些方式来创建文档: GitHub Wiki:在 Github 上我们可 ...