一、spring 概述
Spring是一个轻量级的**控制反转(IoC)和面向切面(AOP)**的容器(框架)。
1.系统架构图
2.入门案例
需求分析:将BookServiceImpl和BookDaoImpl交给Spring管理,并从容器中获取对应的bean对象进行方法调用。
1.创建Maven的java项目
2.pom.xml添加Spring的依赖jar包
3.创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
4.resources下添加spring配置文件,并完成bean的配置
5.使用Spring提供的接口完成IOC容器的创建
6.从容器中获取对象进行方法调用
步骤1:创建Maven项目
步骤2:添加Spring的依赖jar包
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
步骤3:添加spring配置文件
resources下添加spring配置文件applicationContext.xml,并完成bean的配置
二、入门
1.IOC与DI的综合入门案例
- 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean标签标示配置bean
id属性标示给bean起名字,id属性在同一个上下文中(配置文件)不能重复
class属性表示给bean定义类型
-->
<bean id="bookDao" class="com.xiao.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.xiao.service.impl.BookServiceImpl">
<!--配置server与dao的关系-->
<!--property标签表示配置当前bean的属性
name属性表示配置哪一个具体的属性;对应的是BookServiceImpl
ref属性表示参照哪一个bean;对应的是 <bean id="bookDao">
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
2.IOC的内容
2.1bean基础
2.2bean实例化
2.2.1 构造方法
2.2.2 静态工厂
2.2.3 实例工厂与FactoryBean
2.2.4 FactoryBean
具体的使用步骤为:
(1)创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//返回所创建类的Class对象
public Class<?> getObjectType() {
return UserDao.class;
}
}
(2)在Spring的配置文件中进行配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
(3)AppForInstanceUser运行类不用做任何修改,直接运行
2.3 bean的生命周期
- 还有一种接口,在服务层
3.DI的相关内容
我们先来思考
- 向一个类中传递数据的方式有几种?
- 普通方法(set方法)
- 构造方法
- 依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程,如果bean运行需要的是数字或字符串呢?
- 引用类型
- 简单类型(基本数据类型与String)
Spring就是基于上面这些知识点,为我们提供了两种注入方式,分别是:
- setter注入
- 简单类型
- 引用类型
- 构造器注入
- 简单类型
- 引用类型
依赖注入的方式已经介绍完,接下来挨个学习下:
3.1 setter注入
对于setter注入方式的基本使用就已经介绍完了,
- 对于引用数据类型使用的是
<property name="" ref=""/>
- 对于简单数据类型使用的是
<property name="" value=""/>
- 引用数据类型
- 简单数据类型
3.2 构造器注入
3.2.1 构造器注入多个引用数据类型
3.2.2 注入多个简单数据类型
需求:在BookDaoImpl中,使用构造函数注入databaseName和connectionNum两个参数。
参考引用数据类型的注入,我们可以推出具体的步骤为:
1.提供一个包含这两个参数的构造方法
2.在applicationContext.xml中进行注入配置
步骤1:添加多个简单属性并提供构造方法
修改BookDaoImpl类,添加构造方法
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public BookDaoImpl(String databaseName, int connectionNum) {
this.databaseName = databaseName;
this.connectionNum = connectionNum;
}
public void save() {
System.out.println("book dao save ..."+databaseName+","+connectionNum);
}
}
步骤2:配置完成多个属性构造器注入
在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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg name="databaseName" value="mysql"/>
<constructor-arg name="connectionNum" value="666"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
</beans>
**说明:**这两个<contructor-arg>
的配置顺序可以任意
步骤3:运行程序
运行AppForDIConstructor类,查看结果
3.3总结
这节中主要讲解的是Spring的依赖注入的实现方式:
-
setter注入
-
简单数据类型
<bean ...> <property name="" value=""/> </bean>
-
引用数据类型
<bean ...> <property name="" ref=""/> </bean>
-
-
构造器注入
-
简单数据类型
<bean ...> <constructor-arg name="" index="" type="" value=""/> </bean>
-
引用数据类型
<bean ...> <constructor-arg name="" index="" type="" ref=""/> </bean>
-
-
依赖注入的方式选择上
- 建议使用setter注入
- 第三方技术根据情况选择
3.3自动配置
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
<?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 id="bookDao" class="com.xiao.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配 :autowire="byName" 这是按名称-->
<bean id="bookService" class="com.xiao.service.impl.BookServiceImpl" autowire="byType"/>
</beans>
3.4 集合注入
前面我们已经能完成引入数据类型和简单数据类型的注入,但是还有一种数据类型集合,集合中既可以装简单数据类型也可以装引用数据类型,对于集合,在Spring中该如何注入呢?
先来回顾下,常见的集合类型有哪些?
- 数组
- List
- Set
- Map
- Properties
针对不同的集合类型,该如何实现注入呢?
(1)项目中添加添加BookDao、BookDaoImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public class BookDaoImpl implements BookDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties properties;
public void save() {
System.out.println("book dao save ...");
System.out.println("遍历数组:" + Arrays.toString(array));
System.out.println("遍历List" + list);
System.out.println("遍历Set" + set);
System.out.println("遍历Map" + map);
System.out.println("遍历Properties" + properties);
}
//setter....方法省略,自己使用工具生成
}
(2)resources下提供spring的配置文件,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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.xiao.dao.impl.BookDaoImpl">
<!--数组注入-->
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<!--list集合注入-->
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<!--Properties注入-->
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
</beans>
(3)编写AppForDICollection运行类,加载Spring的IOC容器,并从中获取对应的bean对象
public class AppForDICollection {
public static void main( String[] args ) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
说明:
- property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写
<array>
、<list>
、<set>
、<map>
、<props>
标签 - List的底层也是通过数组实现的,所以
<list>
和<array>
标签是可以混用 - 集合中要添加引用类型,只需要把
<value>
标签改成<ref>
标签,这种方式用的比较少
3、IOC/DI配置管理第三方bean
3.1 案例:数据源对象管理
环境准备
-
pom.xml添加依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> </dependencies>
-
resources下添加spring的配置文件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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
-
编写一个运行类App
public class App { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
在上述环境下,我们来对数据源进行配置管理,先来分析下思路:
需求:使用Spring的IOC容器来管理Druid连接池对象
1.使用第三方的技术,需要在pom.xml添加依赖
2.在配置文件中将【第三方的类】制作成一个bean,让IOC容器进行管理
3.数据库连接需要基础的四要素
驱动
、连接
、用户名
和密码
,【如何注入】到对应的bean中4.从IOC容器中获取对应的bean对象,将其打印到控制台查看结果
3.1.1 现Druid管理
步骤1:导入druid
的依赖
pom.xml中添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
步骤2:配置第三方bean
在applicationContext.xml配置文件中添加DruidDataSource
的配置
<?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">
<!--管理DruidDataSource对象-->
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
说明:
- driverClassName:数据库驱动
- url:数据库连接地址
- username:数据库连接用户名
- password:数据库连接密码
- 数据库连接的四要素要和自己使用的数据库信息一致。
步骤3:从IOC容器中获取对应的bean对象
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
步骤4:运行程序
3.1.2 实现C3P0管理
步骤1:导入C3P0
的依赖
pom.xml中添加依赖
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
对于新的技术,不知道具体的坐标该如何查找?
-
直接百度搜索
-
从mvn的仓库
https://mvnrepository.com/
中进行搜索
步骤2:配置第三方bean
在applicationContext.xml配置文件中添加配置
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
<property name="maxPoolSize" value="1000"/>
</bean>
注意:
- ComboPooledDataSource的属性是通过setter方式进行注入
- 想注入属性就需要在ComboPooledDataSource类或其上层类中有提供属性对应的setter方法
- C3P0的四个属性和Druid的四个属性是不一样的
步骤3:运行程序
程序会报错,错误如下
报的错为ClassNotFoundException,翻译出来是类没有发现的异常
,具体的类为com.mysql.jdbc.Driver
。错误的原因是缺少mysql的驱动包。
分析出错误的原因,具体的解决方案就比较简单,只需要在pom.xml把驱动包引入即可。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
添加完mysql的驱动包以后,再次运行App,就可以打印出结果:
注意:
- 数据连接池在配置属性的时候,除了可以注入数据库连接四要素外还可以配置很多其他的属性,具体都有哪些属性用到的时候再去查,一般配置基础的四个,其他都有自己的默认值
- Druid和C3P0在没有导入mysql驱动包的前提下,一个没报错一个报错,说明Druid在初始化的时候没有去加载驱动,而C3P0刚好相反
- Druid程序运行虽然没有报错,但是当调用DruidDataSource的getConnection()方法获取连接的时候,也会报找不到驱动类的错误