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>
测试和结果
总结