Spring入门教程-IoC
Spring概念
Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。
Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且于 2003 年 6 月首次在 Apache 2.0 许可下发布。
Spring 是轻量级的框架,其基础版本只有 2 MB 左右的大小。
Spring 框架的核心特性是可以用于开发任何 Java 应用程序,但是在 Java EE 平台上构建 web 应用程序是需要扩展的。 Spring 框架的目标是使 J2EE 开发变得更容易使用,通过启用基于 POJO 编程模型来促进良好的编程实践。
Spring体系结构
-
底层是核心容器
- Beans
- Core
- Context
- SpringEI表达式
-
中间层技术
- AOP
- Aspects
-
应用层技术
- 数据访问与数据集成
- web集成
- web实现
-
基于Test测试
Spring优点
EJB老版技术
- 方便解耦,简化开发
- 方便集成各种优秀框架
- 方便程序的测试
- AOP编程的支持
- 声明式事务的支持
- 降低javaEE API的使用难度
- java源码是经典学习范例
Ioc简介
简介:
- loc(inversion of control)控制反转,Spring反向控制应用程序所需要使用的外部资源
- spring控制的资源全部放置在spring容器中,该容器称为ioc容器
具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。
耦合与内聚
- 耦合(Coupling):代码书写过程中所使用技术的结合紧密度,用于衡量软件中各个模块之间的互联程度
- 内聚(Cohesion):代码书写过程中单个模块内部各组成部分间的联系,用于衡量软件中各个功能模块内部的功能联系
- 程序书写目标:高内聚,低耦合(就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却不要那么紧密)
入门案例:hello word
-
导入坐标(Maven):pom.xml
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency>
-
配置文件(储存对象到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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1.创建spring控制的资源--> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/> </beans>
-
创建容器对象,根据id获取容器中的对象
public class UserApp { public static void main(String[] args) { //2.加载配置文件,创建容器对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //3.获取资源 UserService userService = (UserService) ctx.getBean("userService"); userService.save(); } }
IOC配置
bean标签属性
id:唯一标识(map的key)
class:指定当前需要创建对象的权限定类名
name: 起别名
scope:【默认spring中的bean是单列】
-
单例singleton(默认):加载配置文件时创建对象,单列容器中当前实列对象永远只有一个
<bean id="userService3" scope="singleton" class="com.itheima.service.impl.UserServiceImpl"/>
-
多例prototype:获取资源时创建对象, 多列容器不会存储对象,而是每次使用创建一个新的
<bean id="userService3" scope="prototype" class="com.itheima.service.impl.UserServiceImpl"/>
bean生命周期
-
init-method
- 在构造方法执行完成后执行初始化方法
-
destroy-method
- 在容器正常关闭的时候执行此方法
配置bean的方式
- 普通bean配置(id, class), 直接反射创建bean放入容器
- 第三方工具有些类不能够直接通过new的方式创建bean
工厂
静态工厂:创建bean的方法是静态方法,也就是不同创建工厂对象
实例工厂
- factoryBean
DI依赖注入
DI(Dependency Injection)依赖注入,应用程序运行依赖的资源由Spring为其提供,资源进入应用 程序的方式称为注入 ,IoC与DI是同一件事站在不同角度看待问题
set注入
作用:给对应对象添加相应属性值
-
给需要属性注入的类添加setter方法
-
到配置文件中使用property标签给对应属性设置值
- value: 普通值
- ref: 这是引用spring中已有的bean
<!-- 1.创建spring控制的资源--> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/> <!--HelloWorld helloworld = new HelloWolrd();--> <!--map.put("helloworld", helloworld)--> <bean id="helloworld" name="hello" class="com.itheima.service.impl.HelloWolrdServlet"> <property name="name" value="gx"/> <property name="userService" ref="userService"/> </bean>
构造器注入
-
在对应的类中生成构造方法
-
在bean标签下面使用constructor-arg标签来指定对应参数的值
- name: 指定参数名
- index: 指定参数的索引
- value:设置普通值
- ref: 设定一个引用值
<!--格式--> <bean> <constructor-arg /> </bean> <!--基本属性--> <constructor-arg name="argsName" value="argsValue />
集合注入
array、list、set、map、props
<!--格式-->
<property>
<list></list>
</property>
<!--List集合类型注入数据-->
<property name="myList">
<list>
<value>itheima</value>
<value>666</value>
<ref bean="userService"/>
<bean class="com.itheima.service.ApplyService"/>
</list>
</property>
<!--Properties类型注入数据-->
<property name="myProps">
<props>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
<!--数组类型注入数据-->
<property name="myArray">
<array>
<value>itheima</value>
<value>666</value>
<ref bean="userService"/>
<bean class="com.itheima.service.ApplyService"/>
</array>
</property>
<!--Set集合类型注入数据-->
<property name="mySet">
<set>
<value>itheima</value>
<value>666</value>
<ref bean="userService"/>
<bean class="com.itheima.service.ApplyService"/>
</set>
</property>
<!--Map集合类型注入数据-->
<property name="myMap">
<map>
<entry key="name" value-ref="itheima"/>
<entry key="fame" value-ref="666"/>
<entry key="userService">
<ref bean="userService"></ref>
</entry>
<entry key="applyService">
<bean class="applyService"/>
</entry>
</map>
</property>
配置文件注入
SpEL:为bean注入属性值
格式:
<property value="EL"></bean>
-
所有格式统一使用 value=“********”
◆ 常量 #{10} #{3.14} #{2e5} #{‘itcast’}
◆ 引用bean #{beanId}
◆ 引用bean属性 #{beanId.propertyName}
◆ 引用bean方法 beanId.methodName().method2()
◆ 引用静态方法 T(java.lang.Math).PI
◆ 运算符支持 #{3 lt 4 == 4 ge 3}
◆ 正则表达式支持 #{user.name matches‘[a-z]{6,}’}
◆ 集合支持 #{likes[3]}
spring加载properties文件
-
编写properties文件
jdbc.username=root password=123321
-
扫描文件
<!--加载properties文件--> <context:property-placeholder location="classpath:data.properties"/>
-
${}获取值
<bean id="propbean" class="com.itheima.domian.PropertiesDemo"> <property name="username" value="${jdbc.username}"/> <property name="pwd" value="${password}"/> </bean>
- 注意:
- properties中的key不要和环境变量中的key冲突
- 如果需要加载所有的properties文件,可以使用*.properties表示加载所有的properties文件
- 读取数据使用${propertiesName}格式进行,其中propertiesName指properties文件中的属性名
import导入其他配置文件
-
加载配置文件是在主配置文件中加载, 对应的key可以在子配置文件中使用idea爆红无所谓
<!--格式--> context:property-placeholder 此标签最好只出现一次 <!--基本属性--> <import resource=“config.xml"/>
-
Spring容器加载多个配置文件
new ClassPathXmlApplicationContext("config1.xml","config2.xml");
spring容器就是存放bean
- 整合: 就是把相应技术的关键类对象存放到spring的容器中
- mybatis
- Resources
- SqlsessionFactoryBuilder
- SqlsessionFactory
- Sqlsession
spring整合Druid
-
原始使用DataSource
public static void main(String[] args) throws SQLException { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/db1"); dataSource.setUsername("root"); dataSource.setPassword("root"); DruidPooledConnection connection = dataSource.getConnection(); }
-
整合步骤
-
导包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> </dependencies>
-
spring配置文件编写
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.200.129:3307/db1"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
-
spring整合MyBatis
- 导入Spring坐标,MyBatis坐标,MySQL坐标,Druid坐标
- 创建数据库表,并制作相应的实体类
- 定义业务层接口与数据层接口
- 在业务层调用数据层接口,并实现业务方法的调用
- jdbc.properties
- MyBatis映射配置文件
- applicationContext.xml
需要管理的bean
spring配置文件,加上context命名空间,用于加载properties文件
-
dao、service层的bean,spring都需要管理
-
dao的bean无需定义,使用代理自动生成,
-
定义service层bean,注入dao层bean,
-
-
mybatis的核心类需要spring管理
- DruidDataSource
- SqlSessionFactoryBean
- MapperScannerConfigurer
mybatis做什么?
-
需要的文件
- applicationContext.xml
- jdbc.properties
- dao接口以及对应的映射配置文件
-
作用:操作数据库
-
mybatis本身处理连接池工作(需要数据库连接池)
<!--加载perperties配置文件的信息--> <context:property-placeholder location="classpath:*.properties"/> <!--加载druid资源--> <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>
-
mybatis需要Sqlsession对象(需要一个创建Sqlsession的工厂)
<!--spring整合mybatis后控制的创建连接用的对象--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.itheima.domain"/> </bean>
-
dao层动态代理实现(动态代理实现的bean必须由spring管理)
- 这些接口的实现类(bean)是由mybatis创建的
<!--加载mybatis映射配置的扫描,将其作为spring的bean进行管理--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.itheima.dao"/> </bean>
-
aSource" ref=“dataSource”/>
```
-
dao层动态代理实现(动态代理实现的bean必须由spring管理)
- 这些接口的实现类(bean)是由mybatis创建的
<!--加载mybatis映射配置的扫描,将其作为spring的bean进行管理--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.itheima.dao"/> </bean>