Spring、
Spring简介
Spring框架是一个开源的JavaEE应用程序,两大核心思想就是IOC(控制反转),DI(依赖注入),AOP(面向切面编程)
Spring IOC
Spring AOP
Spring JDBC+事务
Spring的作用
Dao层
JDBC处理(BaseDao)
对应框架:MyBatis
Service层
Spring框架不是针对Service层业务逻辑,没有合适的框架
Web层(Controller层)
Servlet(接收参数 响应数据 地址配置 页面转发)
对应框架:SpringMVC
Spring框架是基于分布式的应用程序
属于轻量级的框架
配置管理
Bean对象实例化-IOC
集成其他的第三方技术
MyBatis、Hibernate框架(持久层框架)
SpringMVC
Spring Security权限
Quartz时钟框架(定时任务处理)
自带服务
Mail邮件处理
定时任务处理-定时调用(例:定时任务,定时短信)
消息处理(异步处理)
Spring模块划分
Spring IOC模块:Bean对象的实例化 Bean的创建
Spring AOP模块:动态代理 面向切面工程
Spring JDBC+事务模块
Spring Web模块
spring环境搭建
1、先创建Maven项目
选择"File"——>选择"New"——>选择Maven
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0rb0wx9-1592133690573)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591777363897.png)]
2、设置项目的坐标和名字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kgTehrj1-1592133690576)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591777557461.png)]
3、设置项目的Maven环境
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fhTNpgL2-1592133690578)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591777945702.png)]
4、设置项目的名称和存放工作空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AYzUZSBh-1592133690580)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591778070792.png)]
5、修改项目中pom.xml的配置
5.1修改jdk版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
5.2修改单元测试的版本
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
5.3删除 build标签中的pluginManagement标签
<build>
<!--删除 build标签中的pluginManagement标签-->
</build>
5.4添加sping依赖坐标
Maven仓库:https://mvnrepository.com/
<!--添加 Spring 依赖坐标-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
6、添加Spring的配置文件spring.xml
6.1在项目的src下创建文件夹(Alt+insert)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TxwgGnJC-1592133690582)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591833799221.png)]
6.2将文件夹标准为资源目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HWscRxNy-1592133690584)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591833948628.png)]
6.3新建xml文件,将官方文档上的配置拷贝到文件中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kfk72QRH-1592133690585)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591834167775.png)]
<?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">
<bean id="userServices" class="com.shsxt.services.UserServices"></bean>
</beans>
7、创建Bean对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4hvlCmiY-1592133690586)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591834513248.png)]
8、通过spring.xml配置Bean对象
<bean id="userServices" class="com.shsxt.services.UserServices"></bean>
9、加载配置文件,获取实例化对象
public static void main(String[] args) {
//获取到spring上下环境
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
//通过get Bean()方法得到Spring实例化的Bean对像
UserServices userServices= (UserServices) ac.getBean("userServices");
userServices.test();
}
对象实例化模拟实现
1、通过构造器得到相关的配置文件
2、通过dom4j解析xml文件,得到List 存放id和class
3、通过反射实例化得到对象 class.forName(类的全路径).newInstance(); 通过Map(id,class)来存储
4、得到指定实例化的对象
实现步骤:
1、创建接口 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uL5ueTCT-1592133690587)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867286034.png)]
2、向pom.xml添加Dom4j坐标依赖
<!--添加dom4j的坐标依赖-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
3、编写实现代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9dImVlP-1592133690588)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867329070.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eUwH8ncw-1592133690589)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867353152.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7ojeuTH-1592133690590)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867369517.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gD0i1F1j-1592133690591)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867379194.png)]
4、测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wNJTCbgA-1592133690592)(C:\Users\china\AppData\Roaming\Typora\typora-user-images\1591867426284.png)]
Spring IOC核心技术
工厂设计模式(简单工厂 工厂方法 抽象方法)
XML解析(Dom4j Xpath)
反射(实例化对象 反射获取方法 反射获取属性 反射获取构造器)
策略模式(加载资源)
单例(IOC创建的实例化对象都是单例)
Spring IOC配置文件的加载方式
根据相对路径加载资源文件
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
根据绝对路径加载资源文件(了解)
ApplicationContext ac=new FileSystemXmlApplicationContext("D:\\java\\idea_work\\spring02\\src\\main\\resources\\spring.xml");
同时加载多个资源文件
可变参数,传入多个文件名
//同时加载多个资源文件
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml","dao.xml");
通过总的配置文件import配置其他文件
total.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">
<!--导入需要包含的资源文件-->
<import resource="dao.xml"></import>
<import resource="spring.xml"></import>
</beans>
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userServices" class="com.shsxt.services.UserServices">
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
dao.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">
<bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
</beans>
2、加载总的资源文件
//加载总的资源文件
ApplicationContext ac=new ClassPathXmlApplicationContext("total.xml");
Spring IOC 对象实例化
构造器实例化
注:**通过默认构造器创建 空构造方法必须存在 否则创建失败
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
//通过getBean()方法得到实例化对象
//userFactory代表的是配置文件中bean标签的id属性
UserServices userServices= (UserServices) ac.getBean("userServices");
//方法调用
userServices.test();
<bean id="userServices" class="com.shsxt.services.UserServices">
静态工厂实例化(了解)
<!--静态工厂-->
<bean id="userFactory" class="com.shsxt.factory.UserFactory" factory-method="test"></bean>
实例化工厂实例化(了解)
<!--实例化工厂
1.定义实例化工厂 bean
2.引用工厂 bean 指定工厂创建方法(方法为非静态) -->
<bean id="instanceFactory" class="com.shsxt.factory.InstanceFactory"></bean>
<bean id="userService" factory-bean="instanceFactory" factorymethod="createUserService"></bean>
Spring三种实例化bean的方式比较
方式一:通过bean 的缺省构造函数创建,当各个bean的业务逻辑相互比较独立的时候 或者和外界关联较少的时候可以使用。
方式二:利用静态factory方法创建,可以统一管理各个bean的创建,如各个bean在创 建之前需要相同的初始化处理,则可用这个factory方法险进行统一的处理等等。
方式三:利用实例化factory方法创建,即将factory方法也作为了业务bean来控制,
1可用于集成其他框架的bean创建管理方法,2能够使bean和factory的角色互换。
Spring IOC 注入(DI)
手动注入
set(方法)注入
1、属性字段都要提供set方法
//业务对象UserDao set注入
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//常用对象String set注入
private String host;
public void setHost(String host) {
this.host = host;
}
//基本类型Integer set注入
private Integer port;
public void setPort(Integer port) {
this.port = port;
}
//List集合
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
//List集合遍历
public void printList(){
list.forEach(s -> System.out.println(s));
}
//Set集合
private Set<String> set;
public void setSet(Set<String> set) {
this.set = set;
}
//Set集合遍历
public void printSet(){
set.forEach(s -> System.out.println(s));
}
//Map集合
public Map<String,Object> map;
public void setMap(Map<String, Object> map) {
this.map = map;
}
//Map遍历
public void printMap(){
map.forEach((k,v)-> System.out.println(k+","+v));
}
//Properties set注入
public Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
//properties遍历
public void printPro(){
properties.forEach((k,v)-> System.out.println(k+","+v));
}
2、配置文件的bean标签设置property标签
<!--
IOC通过property标签手动注入
name:指bean对象的属性名
ref:指定bean标签的id属性值
value:具体的值(基本数据类型 常用数据类型|日期 集合)
-->
<bean id="userServices" class="com.shsxt.services.UserServices">
<!--set注入-->
<property name="userDao" ref="userDao"></property>
<property name="host" value="192.168.28.249"></property>
<property name="port" value="92"></property>
<!--List集合注入-->
<property name="list">
<list>
<value>北京</value>
<value>上海</value>
<value>深圳</value>
<value>杭州</value>
<value>成都</value>
</list>
</property>
<!--Set集合注入-->
<property name="set">
<set>
<value>北京BJ</value>
<value>上海SH</value>
<value>深圳SZ</value>
<value>杭州HZ</value>
</set>
</property>
<!--Map集合注入-->
<property name="map">
<map>
<entry>
<key><value>周杰伦</value></key>
<value>稻香</value>
</entry>
<entry>
<key><value>林俊杰</value></key>
<value>可惜没有如果</value>
</entry>
</map>
</property>
<!--Properties注入-->
<property name="properties">
<props>
<prop key="北京">天坛</prop>
<prop key="杭州">西湖</prop>
<prop key="上海">东方明珠</prop>
</props>
</property>
</bean>
构造器注入
java代码
提供带参构造器
private UserDao01 userDao01;
private StuDao stuDao;
//常用类型String 构造器注入
private String uname;
//构造器
/* public UserServices01(UserDao01 userDao01) {
this.userDao01 = userDao01;
}*/
/* public UserServices01(UserDao01 userDao01, StuDao stuDao) {
this.userDao01 = userDao01;
this.stuDao = stuDao;
}*/
public UserServices01(UserDao01 userDao01, StuDao stuDao, String uname) {
this.userDao01 = userDao01;
this.stuDao = stuDao;
this.uname = uname;
}
XML配置
<!--
IOC通过构造器注入:
通过constructor-arg标签进行注入
name:属性名称
ref:指定bean标签的id属性值
value:基本数据类型的值
index:构造器中的参数下标
-->
<bean id="userServices01" class="com.shsxt.services.UserServices01">
<constructor-arg ref="userDao01"></constructor-arg>
<constructor-arg ref="stuDao"></constructor-arg>
<constructor-arg name="uname" value="admin"></constructor-arg>
</bean>
<!--Bean对象依赖-->
<bean id="userDao01" class="com.shsxt.dao.UserDao01"></bean>
<bean id="stuDao" class="com.shsxt.dao.StuDao"></bean>
可能出现的问题:循环依赖
java代码:
public class AccountService {
private RoleService roleService;
//构造器
public AccountService(RoleService roleService) {
this.roleService = roleService;
}
/*public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}*/
public void test(){
System.out.println("AccountService Test...");
roleService.test();
}
}
public class RoleService {
private AccountService accountService;
//构造器
public RoleService(AccountService accountService) {
this.accountService = accountService;
}
//
/*public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}*/
public void test(){
System.out.println("RoleService Test....");
accountService.test();
}
}
XML配置文件
<!--
如果多个bean对象互相注入,则会出现循环依赖问题
可通过set方法注入解决
-->
<bean id="roleService" class="com.shsxt.services.RoleService">
<constructor-arg ref="accountService"></constructor-arg>
</bean>
<bean id="accountService" class="com.shsxt.services.AccountService">
<constructor-arg ref="roleService"></constructor-arg>
</bean>
解决构造器注入的循环依赖方法:将构造器注入改为set方法注入
java代码
public class RoleService {
private AccountService accountService;
/*
//构造器
public RoleService(AccountService accountService) {
this.accountService = accountService;
}
*/
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public void test(){
System.out.println("RoleService Test....");
accountService.test();
}
}
public class AccountService {
private RoleService roleService;
/*
//构造器
public AccountService(RoleService roleService) {
this.roleService = roleService;
}
*/
public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
public void test(){
System.out.println("AccountService Test...");
roleService.test();
}
}
<!--修改为set方法注入-->
<bean id="accountService" class="com.shsxt.services.AccountService">
<property name="roleService" ref="roleService"></property>
</bean>
<bean id="roleService" class="com.shsxt.services.RoleService">
<property name="accountService" ref="accountService"></property>
</bean>
静态工厂注入(了解)
1、定义工厂类
//工厂类
public class StaticFactory {
//定义一个TemService类型的静态方法
public static TemService createTemService(){
return new TemService();
}
}
public class TemService {
public void test(){
System.out.println("TemService Test....");
}
}
2、在配置文件中设置bean标签,指定工厂对象并设置对应的方法
<!--静态工厂注入的bean标签-->
<bean id="temService" class="com.shsxt.factory.StaticFactory" factory-method="createTemService"></bean>
实例化工厂注入(了解)
1、定义工厂类
public class InstanceFactory {
public TemService createTemService(){
return new TemService();
}
}
2、声明工厂bean标签,声明bean对象,指明工厂对象和工厂方法
<!--实例化工厂注入得bean标签-->
<bean id="instanceFactory" class="com.shsxt.factory.InstanceFactory"></bean>
<bean id="temService" factory-bean="instanceFactory" factory-method="createTemService"></bean>
自动注入
1、准备环境(修改配置文件)
<?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">
</beans>
2、开启自动注入
<context:annotation-config />
##### 3、给注入的bean对象添加注解
###### @Resource注解
@Resource注解实现自动注入(反射)
1、默认根据属性字段名称查找对应的spring.xml文件中的bean标签
2、如果属性字段名称未找到,则通过类型(class类型)查找
3、属性可以提供set方法,也可以不提供set方法
4、注解可以声明在属性级别或set方法级别
5、@Resource可以设置name属性,name属性值必须与spring.xml中的bean标签的id属性值一致;如果设置了name属性值,就只会按照name属性值查找bean对象
6、当注入接口时,只有一个类实现了该接口则可以正常使用@Resource注入,如果多个类实现了该接口,则需要添加name属性@Resource(name="")指定被需要被实例化的bean对象
```java
@Resource
private UserDao userDao;
@Resource(name ="userDao")
//set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@AutoWired注解
@AutoWired注解实现自动化注入:
1、默认通过类型(class类型)查找bean对象 与属性字段的名称无关
2、属性可以提供set方法,也可以不提供set方法
3、注解可以声明在属性级别或set方法级别
4、可以添加@Qualifier注解结合使用,通过value属性查找bean对象(@Qualifier(value="")value属性值必须设置,且与spring.xml中的bean标签中的id属性值对应)
@Autowired
private AutoDao autoDao;
@Autowired
@Qualifier(value = "autoDao")
//set方法
public void setAutoDao(AutoDao autoDao) {
this.autoDao = autoDao;
}
Spring IOC扫描器
Spring IOC扫描器
作用:将bean对象统一进行管理,简化开发配置,提高开发效率
步骤:
1、设置自动扫描的范围
如果bean对象未在指定包范围,即使声明注解,也无法实例化
2、使用指定的注解(声明在类级别上) bean对象的id属性默认是类的首字母小写
Dao层:
@Repository
Service层:
@Service
Controller层:
@Controller
开发的类实在不明确到底属于哪个层,可以使用@Component注解定义
注:开发过程中建议按照指定规则声明注解
1、设置自动扫描的范围
<!--设置自动扫描的范围-->
<context:component-scan base-package="com.shsxt" />
2、使用特定的注解
//dao层
@Repository
public class ResourceDao {
public void test(){
System.out.println("Hello ResourceDao......");
}
}
//service层
@Service
public class ResourceService {
public void test(){
System.out.println("ResourceService。。。。。。。。");
}
}
//Controller层
@Controller
public class UserController {
public void ucontroller(){
System.out.println("UserController");
}
}
//其他层
@Component
public class UserFactory {
public void test(){
System.out.println("UserFactory.....");
}
}
Bean的作用域
singleton作用域(单例作用域)
Spring IOC容器在实例化对象时,会将单例对象设置到单例缓存池中
lazy-init属性(懒加载)
如果为false,则在IOC容器启动时会实例化bean对象,默认是false
如果为true,则IOC容器启动时不会实例化Bean对象,在使用bean对象时才会实例化
prototype作用域(原型作用域)
Spring IOC容器在实例化对象时,不会将单例对象设置到单例缓存池中,每一次实例都是一次新的对象
Web作用域
request作用域:
在每一次请求实例化一个bean对象
session作用域:
在每一次有效会话实例化一个bean对象
globalSession作用域:
类似于session
Bean的生命周期
Bean的生命周期包括Bean的定义、初始化、使用和销毁4个阶段
定义:
通过配置文件的方式来定义Bean的
初始化(两种方式):
默认在IOC容器加载时,就实例化对象
1、在配置文档中通过指定init-method属性完成
2、实现org.springframework.beans.factory.InitializingBean接口
使用:
销毁:
步骤1:实现销毁方式(Spring容器会维护bean对象的管理,可以指定 bean对象的销毁所要 执行的方法)
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" initmethod="init" destroy-method="destroy"> </bean>
步骤2:通过AbstractApplicationContext 对象,调用其close方法实现bean的销毁过程。
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("Springapplication.xml"); ctx.close();
化对象时,不会将单例对象设置到单例缓存池中,每一次实例都是一次新的对象
#### Web作用域
request作用域:
在每一次请求实例化一个bean对象
session作用域:
在每一次有效会话实例化一个bean对象
globalSession作用域:
类似于session
### Bean的生命周期
Bean的生命周期包括Bean的定义、初始化、使用和销毁4个阶段
定义:
通过配置文件的方式来定义Bean的
初始化(两种方式):
默认在IOC容器加载时,就实例化对象
1、在配置文档中通过指定init-method属性完成
2、实现org.springframework.beans.factory.InitializingBean接口
使用:
销毁:
步骤1:实现销毁方式(Spring容器会维护bean对象的管理,可以指定 bean对象的销毁所要 执行的方法)
<bean id="userServiceImpl"class=“com.shsxt.service.impl.UserServiceImpl” initmethod=“init” destroy-method=“destroy”>
步骤2:通过AbstractApplicationContext 对象,调用其close方法实现bean的销毁过程。
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext(“Springapplication.xml”); ctx.close();