• spring源码解析(二)


    1.spring的扩展:

    我们知道spring和mybatis整合的故事,Spring 2.0 只支持 iBatis 2.0。那么,我们就想将 MyBatis3 的支持添加到 Spring 3.0 中。不幸的是,Spring 3.0 的开发在 MyBatis 3.0 官方发布前就结束了。由于 Spring 开发团队不想发布一个基于未发布版的 MyBatis 的整合支持,如果要获得 Spring 官方的支持,只能等待下一次的发布了。基于在 Spring 中对 MyBatis 提供支持的兴趣,MyBatis 社区认为,应该开始召集有兴趣参与其中的贡献者们,将对 Spring 的集成作为 MyBatis 的一个社区子项目。

    什么是mybatis-spring呢?

    MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,

    以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。

     2.mybatis-spring的使用

    <1>pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>springTest002</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <!-- spring的依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
    
            <!-- mybatis的依赖 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.5</version>
            </dependency>
    
            <!-- mybatis-spring 依赖 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.5</version>
            </dependency>
    
            <!-- 数据库引擎 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.49</version>
            </dependency>
    
            <!-- spring-web -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
                <scope>compile</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
    
        </dependencies>
    
    </project>

    <2>AppConfig.java

    package config;
    
    import mapper.UserMapper;
    import org.apache.ibatis.datasource.pooled.PooledDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.mapper.MapperFactoryBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.sql.DataSource;
    
    @Configuration
    public class AppConfig {
        @Bean
        public DataSource dataSource(){
            PooledDataSource dataSource = new PooledDataSource();
            dataSource.setDriver("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/springtest");
            dataSource.setUsername("root");
            dataSource.setPassword("root");
            return dataSource;
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource());
            return factoryBean.getObject();
        }
    
    //    @Bean
    //    public UserMapper userMapper() throws Exception {
    //        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
    //        return sqlSessionTemplate.getMapper(UserMapper.class);
    //    }
    
        @Bean
        public MapperFactoryBean<UserMapper> userMapper() throws Exception {
            MapperFactoryBean<UserMapper> factoryBean = new MapperFactoryBean<UserMapper>(UserMapper.class);
            factoryBean.setSqlSessionFactory(sqlSessionFactory());
            return factoryBean;
        }
    }

    <3>UserMapper.java

    package mapper;
    
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import pojo.User;
    
    public interface UserMapper {
        @Select("SELECT * FROM student WHERE id = #{userId}")
        User getUser(@Param("userId") String userId);
    }

    <4>Test.java

    public class Test01 {
    
        @Test
        public void hello(){
            System.out.println("aaaa");
            ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
            UserMapper userMapper = (UserMapper)context.getBean("userMapper");
            User user = userMapper.getUser("8");
            System.out.println(user);
        }
    }

    3.实现原理:

    <1>创建一个MyFactoryBean 去实现  FactoryBean 接口FactoryBean的2个方法。

    package bean;
    
    import core.MyInvocationHandler;
    import mapper.UserMapper;
    import org.springframework.beans.factory.FactoryBean;
    
    import java.lang.reflect.Proxy;
    import java.security.PublicKey;
    
    public class MyFactoryBean implements FactoryBean {
    
        public Class MapperInterface;
    
        public MyFactoryBean(Class mapperInterface) {
            MapperInterface = mapperInterface;
        }
    
        public Object getObject() throws Exception {
            Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    new Class[]{MapperInterface}, new MyInvocationHandler());
    
            return o;
        }
    
        public Class<?> getObjectType() {
            return MapperInterface;
        }
    }

    <2>创建一个MyImportBeanDefinitionRegister 去实现 ImportBeanDefinitionRegister接口。

    public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(MyFactoryBean.class);
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("mapper.UserMapper");
            registry.registerBeanDefinition("userMapper",beanDefinition);
    
            RootBeanDefinition beanDefinition2 = new RootBeanDefinition(MyFactoryBean.class);
            beanDefinition2.getConstructorArgumentValues().addGenericArgumentValue("mapper.AccountMapper");
            registry.registerBeanDefinition("accountMapper",beanDefinition2);
        }
    }

    <3>创建AppConfig.java

    @Configuration
    @ComponentScan("bean")
    @Import(MyImportBeanDefinitionRegister.class)
    public class AppConfig {
    }

    <4>Test.java

    public class Test01 {
    
        @Test
        public  void a() {
            ApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
            UserMapper userMapper = (UserMapper)context.getBean("userMapper");
            userMapper.queryList();
            AccountMapper accountMapper = (AccountMapper)context.getBean("accountMapper");
            accountMapper.queryList();
        }
    }
  • 相关阅读:
    java:找出占用CPU资源最多的那个线程
    vue中的样式穿透
    宽度过小,左右浮动元素会下沉的解决方案
    Object.keys方法之详解
    element UI实现动态生成多级表头
    JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄
    JavaScript日期格式化处理
    vue点击编辑按钮,内容变成input可以修改,也可以删除
    NProgress颜色的修改以及在Vue中的使用
    vue中使用raphael.js实现地图绘制
  • 原文地址:https://www.cnblogs.com/takeyblogs/p/13753695.html
Copyright © 2020-2023  润新知