1.Spring简介(了解)
1 Spring概念
Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,可以整合市面上大部分的框架技术。
2 Spring体系结构
3 Spring的优势
2.IOC简介(理解)
1 什么是IOC?
控制反转,控制指的是谁创建对象谁就拥有这个对象的控制权,反转指的是之前的new对象的控制权再我们自己的类手中,现在这个控制权交给了Spring,也就意味着我们使用Spring之后不需要再new对象,应该是从Spring的IOC容器中获取对象。简单来说就是:将new对象的权利交给Spring,我们从Spring的IOC容器中获取即可。
3.入门案例
实现步骤
【第一步】环境搭建
【第二步】导入Spring相关的依赖坐标
【第三步】编写Spring的核心配置文件
【第四步】在单元测试类中从IOC容器中获取对象,调用方法
1.环境搭建
//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 {
}
2.导入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>
3.编写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>
4.在单元测试类中从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();
}
4.Spring配置文件
1.Bean标签基本配置(重要)
<!--
配置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标签范围配置(了解)
作用:控制bean是单例还是多例
- singleton:设定创建出的对象保存在spring容器中,是一个单例的对象,也是默认值
- prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
- request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置
1.单例实例化一次,当Spring核心文件被加载时,实例化配置的Bean实例
2.多例实例化多次,当调用getBean()方法时实例化Bean
<!--
scope="singleton" :单例
scope="prototype" :多例
-->
<bean id="userService" scope="prototype" class="com.itheima.service.impl.UserServiceImpl"/>
3.Bean生命周期配置(了解)
作用:控制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中没有默认无参构造函数,将会创建失败
-
静态工厂方式
public class StaticFactoryBean {
public static UserDao createUserDao(){
return new UserDaoImpl();
}
}
<bean id="userDao" class="com.itheima.factory.StaticFactoryBean"
factory-method="createUserDao" />
- 非静态工厂方法
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标签提前配置)
5.依赖注入(DI)(重点)
依赖注入:在Spring创建对象存的IOC容器时,告诉Spring要给bean的成员变量赋值(也叫注入数据)
1.依赖注入的三种方式
常见异常:找不到bean
- ***set方法注入数据(重要)***
1.需要声明一个变量,并且提供set方法
2.在配置文件中通过<property>标签在<bean>标签中引入
name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)
value:设定非引用类型属性对应的值,不能与ref同时使用
ref:设定引用类型属性对象bean的id,不能与value同时使用
注意: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>
6.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>-->
7.引入外部的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>
8.使用import引入分配置文件
<!--将分配置文件引进来-->
<import resource="classpath:applicationContext-dao.xml"/>
注意:如果主配置文件和分配置文件都配置了相同id的bean,那么后配置的会覆盖先配置的。同一个配置文件中不能配置相同id的bean。
5.综合案例(重要)
整合步骤
1 导入spring整合mybatis的依赖
mybatis-spring、spring-jdbc
2 在applicationContext.xml中整合mybatis
连接池(需要导入依赖坐标)、SqlSessionFactoryBean、MapperScannerConfigurer
3 修改Service和测试类代码
service中只需要调用dao就行了,测试类中从spring容器中获取service对象,调用方法
1.导入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>
2.在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
3.修改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也就是找不到映射文件
6.spring相关API
6.1 ApplicationContext的继承体系
applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
6.2 ApplicationContext的实现类
1)ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件 推荐使用这种
2)FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
3)AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
6.3 getBean()方法使用
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错
getBean()方法使用
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("userService");
UserService userService2 = applicationContext.getBean(UserService.class);
总结
基本概念
1- spring是什么
spring是一个轻量级的Java开发框架,可以解决业务逻辑层和其他各层的耦合问题,可以整合市面上大部分的框架
2- 什么是IOC
控制反转:就是把new对象的权利交给spring,我们只需要从Spring的IOC容器中获取
3- 什么是DI
依赖注入:在Spring创建对象存在的IOC容器时,告诉Spring要给bean的成员变量赋值
4- Spring配置文件
4.1基本配置:
*id:bean对象存到IOC容器的唯一标识
*class:bean的全类名,底层会通过反射技术创建对象存在IOC容器
4.2范围配置:
*singleton:单例对象,默认值,单例实例化一次,当spring核心文件被加载的时候,实例化配置的Bean实例
*prototype:多例,多例实例化多次,当调用getBean()方法时实例化Bean
4.3 生命周期:
前提:bean类中有init()和destroy()方法
*init-method="init":定义bean类中的init方法为初始化方法
*destroy-method="destroy":定义bean中的destroy方法为销毁方法,该方法想要执行需要关闭spring容器
4.4 实例化的三种方式:
*使用无参构造方法实例化
*静态工厂
*非静态工厂
4.5 依赖注入的三种方式
*set注入
name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)
value:设定非引用类型属性对应的值,不能与ref同时使用
ref:设定引用类型属性对象bean的id,不能与value同时使用
*构造器注入
*p命名空间注入
4.6 导入分配置文件
<import resource="classpath:xxx.xml"/>
spring整合mybatis (applicationContext.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"
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">
<!--导入jdbc配置文件-->
<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>
<!--spring整合mybatis后控制的创建连接对象-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--指定数据源-->
<property name="dataSource" ref="dataSource"/>
<!--取别名-->
<property name="typeAliasesPackage" value="com.itheima.domain"/>
</bean>
<!--加载mybatis映射配置的扫描,将其作为spring的bean进行管理-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.dao"/>
</bean>
<!--配置service-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
</beans>