Spring如何创建复杂对象以及Spring整合Mybatis思路分析

1. spring如何创建复杂对象

# spring如何创建复杂对象

1. spring  项目管理框架 	
		定义:	spring 项目管理框架  spring框架主要负责项目中 组件对象的 创建 使用 销毁
			  spring 工厂 容器  ===>  对象  ===> 对象唯一标识
2. spring框架如何管理组件对象的创建
	
	a). 组件对象	UserDAO  UserDAOImpl	UserService	UserServiceImpl
	
	b).	工厂中创建
			<bean class="com.baizhi.do.UserDAOImpl" id="userDAO">
		
	c).	获取组件对象
			UserDAO userDAO = (UserDAO) new ClassPathXmlApplicationContext(spring.xml).getBean("userDAO")
	
	d).	工厂原理
			反射
			Class.forName("com.baizhi.dao.UserDAOImpl").newInstance();// ===> 通过反射调用类中无参构造方法进行创建
			这里也说明在spring中类无论如何都必须有一个无参的构造方法
			
3. 通过工厂创建简单对象
	 简单对象:可以直接通过new关键字创建的对象 统一称为简单对象
	 工厂创建时: <bean class="" id="">
	 
4. 通过工厂创建复杂对象
	 复杂对象:	不能直接通过new关键字进行创建的对象|  接口类型 Connection | 抽象类类型 Calendar MessageDisgest...
	 																			日历		加密
	 工厂创建复杂对象:							
	 							// 泛型写Calendar表明要创建日历对象,泛型写Connection表明要创建连接对象
	 	类					   // 也就是说日后要创建的复杂对象(抽象类、接口)是谁,泛型就写谁
	 	1. 对象名FactoryBean  implements  FactoryBean<Calendar>{   
            // 用来书写复杂对象的创建方式
            // spring不知道怎么创建这个复杂对象,但是你自己直到如何创建,所以这个是用来书写复杂对象的创建方式的方法
            public Calendar getObject() throws Exception {
                return Calendar.getInstance();
            }
            // 指定创建的复杂对象的类型
            public Class<?> getObjectType() {
                return Calendar.class;
            }
            // 用来指定创建的对象的模式   true 单例  false 多例
            public boolean isSingleton() {
                return true;
            }
	 	 }
	    2. 通过工厂配置创建复杂对象
	    					  // 包.类名
	   		<bean id="calendar" class="xxxx.CalendarFactoryBean">
	   	3. 在工厂中获取(没变,和简单对象一样)
	   		ApplicationContext context = new ClassPathXmlApplicationContext("factorybean/spring.xml");
            Calendar calendar = (Calendar) context.getBean("calendar");

日后再通过工厂管理对象时,首先要判断它是否是简单对象:

  • 简单对象的管理直接在工厂配置
  • 复杂对象的管理先实现FactoryBean,然后在工厂配置

小知识

  • Calendar:日历类,它是一个抽象类

    •  public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
      
    •  // Calendar是一个抽象类,不能直接通过new关键字去创建,只能通过它的静态方法去创建
       Calendar calendar = Calendar.getInstance();
       // 当前系统时间
       System.out.println(calendar.getTime());
      
  • Connection:连接类,它是一个接口

    •   public interface Connection  extends Wrapper, AutoCloseable {
      
    •   // Connection是一个接口,不能直接通过new关键字创建,只能通过DriverManager的getConnection方法创建
        Class.forName("driver");
        Connection conn = DriverManager.getConnection("url", "username", "password");
        System.out.println(conn);
      

在spring工厂中对于简单对象可以直接使用 这种方式进行对象创建,那什么是简单对象呢,简单对象就是可以直接通过new关键字进行创建的对象

有简单对象那就一定有复杂对象,复杂对象不能直接通过new关键字创建的对象,比如抽象类接口

下面我们通过一个小案例证明一下抽象类不能通过创建简单对象的方式去创建

配置文件

在这里插入图片描述

测试和结果

在这里插入图片描述

那么如何创建复杂对象呢,接下来我们以两个案例来熟悉复杂对象的创建流程

案例一:创建复杂对象Calendar

我们来创建复杂对象Calendar,它是一个抽象类,属于复杂对象

首先,我们需要实现FactoryBean接口,并重写里面的方法

// 用来在工厂中创建复杂对象
public class CalendarFactoryBean implements FactoryBean<Calendar> {
    // 用来书写复杂对象的创建方式
    // spring不知道怎么创建这个复杂对象,但是你自己直到如何创建,所以这个是用来书写复杂对象的创建方式的方法
    public Calendar getObject() throws Exception {
        return Calendar.getInstance();
    }
    // 指定创建的复杂对象的类型
    public Class<?> getObjectType() {
        return Calendar.class;
    }
    // 用来指定创建的对象的模式   true 单例  false 多例
    public boolean isSingleton() {
        return true;
    }
}

在spring中对于复杂对象的创建需要实现FactoryBean<>接口里面写要创建的复杂对象的类,另外还要重写三个方法:

  • 方法一:

    • public Calendar getObject() throws Exception {
              return Calendar.getInstance();
          }
      
    • 这个方法是用来书写创建复杂对象的方法的,spring不知道复杂对象的创建方式,但是你自己是知道怎么创建这个复杂对象的,这个方法的返回类型也是你要创建的复杂对象的类型。

  • 方法二:

    • // 指定创建的复杂对象的类型
      public Class<?> getObjectType() {
          return Calendar.class;
      }
      
    • 指定创建的复杂对象的类型返回创建的复杂对象的class,直接返回复杂类.class

  • 方法三:

    • // 用来指定创建的对象的模式   true 单例  false 多例
      public boolean isSingleton() {
          // 这里例子中指定为了单例
          return true;
      }
      
    • 用来指定创建复杂对象的模式,返回true表示创建模式是单例,返回false表示创建模式是多例

在这里插入图片描述

配置文件

<!--通过factorybean创建复杂对象-->
<!--虽然class是实现类,但是id还是建议以复杂类名字形式写-->
<bean class="factorybean.CalendarFactoryBean" id="calendar"></bean>

在这里插入图片描述

测试+结果

在这里插入图片描述

案例二:创建复杂对象Connection连接对象

实现FactoryBean接口,并重写方法

public class ConnectionFactoryBean implements FactoryBean<Connection> {
    public Connection getObject() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/lb", "root", "root");
    }

    public Class<?> getObjectType() {
        return Connection.class;
    }

    public boolean isSingleton() {
        return false;
    }
}

配置文件

<bean class="factorybean.ConnectionFactoryBean" id="conn"></bean>

测试和结果

在这里插入图片描述

总结:

在这里插入图片描述

2. spring整合mybatis思路分析

# Spring整合Mybatis
			思路分析 ====> SM整合

1. 引入相关依赖
   spring mybatis mysql ...
   
2. 如何整合
   
   Spring		项目管理框架		主要是用来负责项目中组件对象的创建、使用、销毁
   
   Mybatis		持久层框架		主要是用来简化原始jdbc技术对数据库的访问操作	操作数据库  mybatis中核心对象----数据库
   
   整合思路:	通过Spring框架接管Mybatis框架中核心对象的创建	
   
3. Mybatis框架中核心对象是谁?

	Mybatis中最核心的对象:SqlSessionFactory  在创建时一定要读取mybatis-config

	SqlSessionFactoryBuilder	(这个对象的作用其实就是读取mybatis-config配置文件)
	SqlSessionFactory			读取mybatis-config   [数据源配置  mapper文件配置]
	sqlSession
	dao
	
4. SM整合spring整合mybatis框架
	整合思路:通过Spring框架接管Mybatis中核心的SqlSessionFactory对象的创建
	
	a). spring如何管理SqlSessionFactory对象的创建
		简单对象: <bean class="" id="">
		复杂对象: 类 implements FactoryBean<类>
		
		SqlSessionFactory:通过查看源码得知它是一个接口类型的复杂对象
		
		如何创建:
			InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder.build(is);
			
			//本来类名是两个Factory,但因为在java规范里两个相同的连到一起省略一个,所以下面类名中只有一个Factory
		1). SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>{
				public SqlSessionFactory getObject() throws Exception {
                	InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
					return new SqlSessionFactoryBuilder.build(is);
            	}
                // 指定创建的复杂对象的类型
                public Class<?> getObjectType() {
                    return SqlSessionFactory.class;
                }
                // 用来指定创建的对象的模式   true 单例  false 多例
                public boolean isSingleton() {
                    return true;
                }
			}
			
		2). 工厂管理SqlSessionFactory
			<bean class="xxx.SqlSessionFactoryBean" id="sqlSessionFactory">
			
		3). 工厂获取
			SqlSessionFactory sf = (SqlSessionFactory) context.getBean("sqlSessionFactory");
			
5. Mybatis官方
		Mybatis-spring jar包  封装了SqlSessionFactory对象的创建  这个jar包里有SqlSessionFactoryBean
		
		也就是说我们以后可以不用自己创建SqlSessionFactoryBean了,直接用Mybatis-spring jar里面封装了已经
		
		创建好的SqlSessionFactoryBean
		
		    <!--mybatis-spring-->
            <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis-spring</artifactId>
              <version>2.0.4</version>
            </dependency>
            
         注意:mybatis官方提供的SqlSessionFactoryBean  不能再使用mybatis-config主配置文件
         mybatis-config主配置文件中最重要的数据源和mapper文件注册
         
         当我们使用mybatis官方提供的SqlSessionFactoryBean,需要在spring.xml中注册数据源对象
         注册mapper文件配置
         
6.  创建数据源对象 这里使用阿里的druid工具类

		引入依赖
		    <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>druid</artifactId>
              <version>1.1.19</version>
            </dependency>
			
		创建数据源
		    <!--创建数据源-->
            <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
                <!--name必须写driverClassName,因为jar包里定义的成员变量的名字就是driverClassName-->
                <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </bean>
		

接下来我们来看看整合Spring和Mybatis的思路,以及如何整合Spring和Mybatis

Mybatis核心对象SqlSessionFactory对象,因此对于Spring来说,整合mybatis就相当于把SqlSessionFactory对象的创建交给Spring去管理

首先,我们需要在pom.xml文件中引入spring、mybatis、mysql、mybatis-spring相关依赖

<!--引入mybatis相关jar包-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.2.8</version>
</dependency>

<!--引入spring相关jar包-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.2.RELEASE</version>
  </dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>

<!--引入mysql相关jar包-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.40</version>
</dependency>

<!--引入mybatis-spring  jar包-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.3.1</version>
</dependency>

因为SqlSessionFactory是一个接口,是一个复杂对象,如果Spring想要管理它,需要先创建一个实现类实现接口FactoryBean,这里我们创建类SqlSessionFactoryBean实现FactoryBean接口

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory> {

    private String configLocations;

    public void setConfigLocations(String configLocations) {
        this.configLocations = configLocations;
    }

    public SqlSessionFactory getObject() throws Exception {
                                                        // 如果这里直接写mybatis-config.xml则太固定了,不灵活
                                                        // 所以定义一个成员变量,以后想要读哪个配置文件,就把
                                                        // 配置文件的路径赋值给成员变量configLocations
        InputStream is = Resources.getResourceAsStream(configLocations);
        return new SqlSessionFactoryBuilder().build(is);
    }

    public Class<?> getObjectType() {
        return SqlSessionFactory.class;
    }

    public boolean isSingleton() {
        return true;        // 返回true表示在工厂中创建的SqlSessionFactory对象是单例的
    }
}

在这里插入图片描述

配置mybatis的主配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>

    </mappers>
</configuration>

在这里插入图片描述

配置spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--管理SqlSessionFactory-->
    <bean class="factorybean.SqlSessionFactoryBean" id="sqlSessionFactory">
        <property name="configLocations" value="mybatis-config.xml"/>
    </bean>

</beans>

在这里插入图片描述

测试和结果

在这里插入图片描述

上面就是我们使用自己实现了FactoryBean接口的实现类整合mybatis和spring的案例,因为创建实现FactoryBean接口的实现类写法很常用,所以mybatis官方封装了这个实现类。我们来看一下:

当我们实现官方实现的FactoryBean接口的实现类,我们需要在pom.xml文件中引入依赖mybatis-config

<!--mybatis-spring-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>

在这里插入图片描述

当我们使用官方实现的FactoryBean的实现类时,我们不能再使用mybatis的主配置文件mybatis-config.xml了,但是这不要紧,mybatis-config中最重要的是数据源和mapper配置文件,这些我们可以直接写到spring.xml中。但是在这之前我们需要一些前置操作。

从下面这张图我们可以了解什么是数据源,什么是mapper文件注册

在这里插入图片描述

  • 在写数据源时我们需要使用阿里巴巴的druid工具类,我们要在pom.xml文件中引入依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.19</version>
    </dependency>
    
  • 测试数据源类

    在这里插入图片描述

注意:一旦我们使用了mybatis官方的实现了FactoryBean接口的工具类,我们就不能使用mybatis主配置文件mybatis-config.xml了,我们必须自己写配置源、mapper配置文件,也就是说这时mybatis-config.xml可有可无了。

配置spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--创建数据源-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <!--name必须写driverClassName,因为jar包里定义的成员变量的名字就是driverClassName-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>


    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--依赖数据源对象-->
        <property name="dataSource" ref="dataSource"></property>
        <!--依赖mapper文件注册-->
<!--        <property name="mapperLocations">-->
<!--            <array>-->
<!--                <value>com/baizhi/mapper/UserDAOMapper.xml</value>-->
<!--            </array>-->
<!--        </property>-->
    </bean>

</beans>

在这里插入图片描述

测试和结果

在这里插入图片描述

总结

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值