• spring动态添加bean


    不知道大家想过没有,我们使用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;
        }
  • 相关阅读:
    阿里云help
    Docker 介绍和使用
    LoadRunner 技巧之 IP欺骗
    LoadRunner 技巧之THML 与 URL两种录制模式分析
    LoadRunner使用动态链接库技术
    浅谈软件性能测试中关键指标的监控与分析
    如何准备性能测试数据
    LoadRunner检查点使用小结
    LoadRunner性能测试样例分析
    web性能测试基本性能指标
  • 原文地址:https://www.cnblogs.com/MonsterJ/p/12518647.html
Copyright © 2020-2023  润新知