【第一章】Spring简介【了解】
1 Spring概念
Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,可以整合市面上大部分的框架技术.
2 Spring体系结构
3 Spring的优势
【第二章】IOC简介【理解】
1 什么是IOC?
控制反转,控制指的是谁创建对象谁就拥有这个对象的控制权,反转指的是之前的new对象的控制权再我们自己的类手中,现在这个控制权交给了Spring,也就意味着我们使用Spring之后不需要再new对象,应该是从Spring的IOC容器中获取对象。简单来说就是:将new对象的权利交给Spring,我们从Spring的IOC容器中获取即可。
【第三章】入门案例
1 实现步骤
【第一步】环境搭建
【第二步】导入Spring相关的依赖坐标
【第三步】编写Spring的核心配置文件
【第四步】在单元测试类中从IOC容器中获取对象,调用方法
【第一步】环境搭建
//1 创建maven工程
//2 创建UserService和UserServiceImpl实现类
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("UserServiceImpl save is running...");
}
}
//3 创建单元测试类
public class SpringTest {
}
【第二步】导入Spring相关的依赖坐标【重要】
核心依赖:spring-context
<dependencies>
<!--spring的核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--junit,和spring没有关系-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
【第三步】编写Spring的核心配置文件【重要】
鼠标右键------->new------>xml configuration file------>spring config
<?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">
<!--
配置UserService,将UserService交给spring创建管理,存到IOC容器中
id="userService" :bean对象存到IOC容器中的唯一标识,不能重复
class="" :bean全类名,底层会通过反射技术创建对象存到IOC容器中
-->
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>
</beans>
【第四步】在单元测试类中从IOC容器中获取对象,调用方法【重要】
@Test
public void test1(){
//1 创建Spring核心对象
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
//2 从容器中根据id值获取对象
//UserService userService = (UserService) ac.getBean("userService");
UserService userService = ac.getBean("userService", UserService.class);
//3 调用对象的方法
userService.save();
}
【第四章】IOC配置(XML格式)
1 Bean标签的id、name(了解)、class属性【重要】
<!--
配置UserService,将UserService交给spring创建管理,存到IOC容器中
id="userService" :bean对象存到IOC容器中的唯一标识,不能重复
class="" :bean全类名,底层会通过反射技术创建对象存到IOC容器中
name="" :bean对象的名称,相当于别名,可以取多个,用逗号隔开
-->
<bean id="userService" name="userService2,userService3,userService4" class="com.itheima.service.impl.UserServiceImpl"/>
2 Bean标签的scope属性【了解】
作用:控制bean是单例还是多例
- singleton:设定创建出的对象保存在spring容器中,是一个单例的对象,也是默认值
- prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
- request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置
<!--
scope="singleton" :单例
scope="prototype" :多例
-->
<bean id="userService" scope="prototype" class="com.itheima.service.impl.UserServiceImpl"/>
3 Bean标签的init-method和destroy-method属性【了解】
作用:控制bean的声明周期方法
前提:我们的bean类中要有init()方法和destroy()方法
<!--
init-method="init":定义bean中的init方法是初始化方法
destroy-method="destroy":定义bean中的destroy方法是销毁方法,该方法要想执行需要关闭spring容器。
-->
<bean id="userService"
scope="prototype"
class="com.itheima.service.impl.UserServiceImpl"
init-method="init"
destroy-method="destroy"/>
4 静态工厂和非静态工厂创建bean
静态工厂方式:
<!--
静态工厂创建bean对象
例如:Calendar calendar=Calendar.getInstance();
-->
<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"/>
非静态工厂方法:
public class UserServiceFactory {
//非静态方法
public UserService getBean(){
return new UserServiceImpl();
}
}
<!--
非静态工厂创建bean对象
UserServiceFactory factory=new UserServiceFactory();
UserService userService = factory.getBean();
-->
<bean id="factory" class="com.itheima.factory.UserServiceFactory"/>
<bean id="userService" factory-bean="factory" factory-method="getBean"/>
总结bean的属性:
id(bean的唯一标识)
class(bean的全类名,Spring根据全类名反射创建对象)
name(bean的名称,类似于别名)
scope(singleton表示单例,prototype表示多例,默认是单例)
init-method(给bean配置生命周期的初始化方法)
destroy-method(给bean配置生命周期的销毁方法)
factory-method(配置从工厂方法中获取对象,如果没有配置factory-bean表示从静态工厂方法中获取对象)
factory-bean(配置从哪个工厂对象中获取bean对象,这个工厂是非静态工厂,需要使用bean标签提前配置)
2 依赖注入(DI)【重点】
依赖注入:在Spring创建对象存的IOC容器时,告诉Spring要给bean的成员变量赋值(也叫注入数据)
1 依赖注入的三种方式
常见异常:找不到bean
set方法注入数据(重要)
注意:bean中必须要有set方法,如果没有就报错。
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
构造器方式注入数据(次重要)
【第一步】在类中添加构造方法
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
【第二步】在applicationContext.xml中注入数据
<!--配置UserService-->
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<!--
name="userDao":表示构造方法中的参数名称
ref="userDao" :表示注入的对象,被注入的对象一定要存在于spring容器,没有就报错
value="武汉": 表示注入普通类型数据,例如基本类型+String
type="com.itheima.dao.UserDao" :表示按照类型注入数据,少用
index="0":表示按照索引给参数注入数据,少用
-->
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="address" value="武汉"/>
<!--<constructor-arg type="com.itheima.dao.UserDao" ref="userDao"/>
<constructor-arg type="java.lang.String" value="武汉"/>-->
</bean>
<!--配置UserDao-->
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
p名称空间注入数据(了解)
【第一步】引入p名称空间
xmlns:p="http://www.springframework.org/schema/p"
【第二步】使用p名称空间注入数据
<!--p名称空间注入数据-->
<bean
id="userService"
class="com.itheima.service.impl.UserServiceImpl"
p:userDao-ref="userDao"
p:address="武汉黄皮"
/>
注意:变量要有set方法
2 注入复杂类型的数据(了解)
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<!--private String[] hobbies;-->
<property name="hobbies">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>
</array>
</property>
<!--private List<String> list;-->
<property name="list">
<list>
<value>aaa</value>
<value>bbb</value>
</list>
</property>
<!--private Set<Integer> numbers;-->
<property name="numbers">
<set>
<value>134</value>
<value>66666666</value>
</set>
</property>
<!--private Map<String,Integer> hashMap;-->
<property name="hashMap">
<map>
<entry key="age" value="10"/>
<entry key="phone" value="1361234"/>
</map>
</property>
<!--private Properties properties;-->
<property name="properties">
<props>
<prop key="姓名">老李</prop>
<prop key="地址">武汉</prop>
</props>
</property>
</bean>
3 Spring中配置第三方bean对象【重要】
<!--配置druid连接池-->
<!--
DruidDataSource ds=new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/db3");
ds.setUsername("root");
ds.setPassword("root");
-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db3"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--
DruidDataSource ds=DruidDataSourceFactory.createDataSource(Properties);
将方法中的参数当作构造方法参数处理,了解
-->
<!--<bean id="ds" class="com.alibaba.druid.pool.DruidDataSourceFactory" factory-method="createDataSource">
<constructor-arg name="properties">
<props>
<prop key="driverClassName">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql://localhost:3306/db3</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</constructor-arg>
</bean>-->
4 引入外部的properties属性文件【重要】
【第一步】导入context名称空间
【第二步】使用标签
<!--引入properties属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
【第三步】使用EL表达式取值
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
5 使用import引入分配置文件
<!--将分配置文件引进来-->
<import resource="classpath:applicationContext-dao.xml"/>
注意:如果主配置文件和分配置文件都配置了相同id的bean,那么后配置的会覆盖先配置的。同一个配置文件中不能配置相同id的bean。
【第五章】综合案例【重要】
1 整合步骤
1 导入spring整合mybatis的依赖
mybatis-spring、spring-jdbc
2 在applicationContext.xml中整合mybatis
连接池(需要导入依赖坐标)、SqlSessionFactoryBean、MapperScannerConfigurer
3 修改Service和测试类代码
service中只需要调用dao就行了,测试类中从spring容器中获取service对象,调用方法
【第一步】导入spring整合mybatis的依赖
<dependencies>
<!--mybatis和mysql依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--spring整合mybatis***********-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.1</version>
</dependency>
<!--spring-jdbc操作***************-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--连接池要交给spring-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
</dependencies>
【第二步】在applicationContext.xml中整合mybatis【核心】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--引入属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置service-->
<bean id="studentService" class="com.itheima.service.impl.StudentServiceImpl">
<property name="mapper" ref="studentMapper"/>
</bean>
<!--spring整合mybatis-->
<!--SqlSessionFactoryBean用来创建SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--必须有-->
<property name="dataSource" ref="dataSource"/>
<!--配置别名-->
<property name="typeAliasesPackage" value="com.itheima.bean"/>
<!--配置mybatis的核心配置文件的位置,核心配置文件中也可以设置别名、映射文件位置等操作-->
<!--<property name="configLocation" value="classpath:MybatisConfig.xml"/>-->
<!--如果映射文件和mapper接口在同一个包下-->
<!--<property name="mapperLocations" value="classpath:StudentMapper.xml"/>-->
</bean>
<!--MapperScannerConfigurer 扫描mapper接口,生成代理对象,存的spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描mapper所在的包,映射文件需要和包在一起,如果不在一起,就需要在SqlSessionFactoryBean中配置额外指定-->
<property name="basePackage" value="com.itheima.mapper"/>
</bean>
</beans
【第三步】修改Service和测试类代码
service类代码:
public class StudentServiceImpl implements StudentService {
private StudentMapper mapper; //注入的是mapper的代理对象
public void setMapper(StudentMapper mapper) {
this.mapper = mapper;
}
@Override
public List<Student> selectAll() throws IOException {
return mapper.selectAll();
}
@Override
public Student selectById(Integer id) throws IOException {
return mapper.selectById(id);
}
@Override
public Integer insert(Student stu) throws IOException {
return mapper.insert(stu);
}
@Override
public Integer update(Student stu) throws IOException {
return mapper.update(stu);
}
@Override
public Integer delete(Integer id) throws IOException {
return mapper.delete(id);
}
}
测试类代码:
public class StudentTest {
@Test
public void test1() throws IOException {
//创建Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取service对象
StudentService studentService = ac.getBean("studentService", StudentService.class);
//执行操作,调用service的方法
List<Student> list = studentService.selectAll();
list.forEach(stu-> System.out.println(stu));
}
@Test
public void test2() throws IOException {
//创建Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取service对象
StudentService studentService = ac.getBean("studentService", StudentService.class);
//执行操作,调用service的方法
Student stu = studentService.selectById(6);
System.out.println("stu = " + stu);
}
}
常用异常
找不到sql也就是找不到映射文件