本部分理解原理就好
Spring入门
1 Spring引入
1.1 原生web开发中存在的问题
传统Web开发存在硬编码所造成的过度程序耦合(例如:Service中作为属性Dao对象)。
部分Java EE API较为复杂,使用效率低(例如:JDBC开发步骤)。
侵入性强,移植性差(例如:DAO实现的更换,从Connection到SqlSession)。
2 Spring
2.1 Spring的概念
- Spring框架是一个轻量级开放源代码JavaEE应用程序一站式框架,其主要核心为IOC和AOP
- 轻量级开放源代码
- 开源免费,轻量级框架指的是不依赖其他的框架能独立使用 (EJB)
- 一站式
- 表现层 Servlet SpringMVC
- 业务层 Service Spring在整个web项目中起到承上启下的作用
- 数据层 JDBC SpringDataJpa
- IOC和AOP (面试重点难点)
- IOC(控制反转) 以前创建对象 UserDao user = new UserDao();
- 将对象的创建交个Spring框架(容器)
- DI(依赖注入) 即给对象属性赋值
- AOP(面向切面)
- 在不修改原代码的情况,对象功能进行增强 (零入侵式编程,不修改源代码的前提下)
- 底层原理(动态代理)
2.2 Spring 作用
Spring是一个项目管理框架,同时也是一套Java EE解决方案。
Spring是众多优秀设计模式的组合(工厂、单例、代理、适配器、包装器、观察者、模板、策略)。
Spring并未替代现有框架产品,而是将众多框架进行有机整合,简化企业级开发,俗称"胶水框架"。
2.3 Spring的组成
Spring架构由诸多模块组成,可分类为
- 核心技术:依赖注入,事件,资源,i18n,验证,数据绑定,类型转换,SpEL,AOP。
- 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient。
- 数据访问:事务,DAO支持,JDBC,ORM,封送XML。
- Spring MVC和 Spring WebFlux Web框架。
- 集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
- 语言:Kotlin,Groovy,动态语言。
2.4 spring的IOC底层实现原理
spring的IOC底层实现原理 |
---|
![]() |
3 Spring快速入门
- 父工程pom.xml 引入spring依赖
spring-context
- spring的配置文件 applicationContext.xml 配置
bean
的信息- 创建spring容器获取对象
3.1 引入spring依赖
Context包含了beans、core、context、expression
如果是只是IOC的开发,那么只需要导入Spring的四个核心就可以了
<!-- 父工程记得修改打包方式-->
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
3.2 spring的配置文件
applicationContext.xml 文件配置
Spring的IOC功能就是将对象的创建交给SpringIOC容器,然后需要使用的时候直接去Spring中获取即可
<?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="userDao" class="com.ying.dao.impl.UserDaoImpl"/>
</beans>
3.3 测试
创建Spring容器,获取对象实例
public class SpringTest {
@Test
public void test01(){
//以前:通过new的方式直接获取UserDao对象
UserDao userDao = new UserDaoImpl();
userDao.addUser();
}
@Test
public void test02(){
//现在:通过Spring容器获取UserDao对象
//获取SpringIOC容器
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = ac.getBean("userDao", UserDao.class);
userDao.addUser();
}
4 Spring的开发细节
4.1 BeanFactory的类间关系
- SpringIOC容器类的结构
- 最顶层的接口 BeanFactory
- 子接口: ApplicationContext
- ClassPathXmlApplicationContext 针对类路径下的xml文件配置的方式
- AnnotationConfigApplicationContext 针对纯注解式开发配置的方式
- FileSystemXmlApplicationContext 针对系统路径下的xml文件配置的方式
- BeanFactory 和ApplicationContext 区别
- BeanFactory使用的懒加载的形式,对象在使用的时候才会创建
- ApplicationContext,当程序启动的时候会直接加载配置文件创建对象 (web推荐使用)
@Test
public void test01(){
//创建Spring容器对象 ApplicationContext
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
Object userDao = ac.getBean("userDao1");
System.out.println(userDao);
}
@Test
public void test02(){
//创建Spring容器对象 BeanFactory
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
Object userDao1 = beanFactory.getBean("userDao1");
System.out.println(userDao1);
}
4.2 getBean方法
- getBean(“对象id标识”);
- getBean(类对象);
- getBean(“对象id标识”,类对象);
@Test
public void test03(){
//创建Spring容器对象 ApplicationContext
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//缺点:获取对象的时候需要强制转换
//UserDao userDao = (UserDao) ac.getBean("userDao1");
//userDao.addUser();
//缺点:如果一个类有多个对象,则报错
//UserDao userDao = ac.getBean(UserDaoImpl.class);
//userDao.addUser();
UserDaoImpl userDao1 = ac.getBean("userDao1", UserDaoImpl.class);
UserDaoImpl userDao2 = ac.getBean("userDao2", UserDaoImpl.class);
userDao1.addUser();
userDao2.addUser();
}
4.3 bean标签中的scope属性
- scope属性的取值
- singleton :表示创建的对象是单例的(默认取值)
- prototype :表示创建的对象是原型模型
- 基于web
- request :表示创建的对象再request范围内
- session :表示创建的对象再session范围内
- globalSession : Spring5.X弃用
<!-- 设置为单例模式(默认单例) -->
<bean id="userDao2" class="com.ying.dao.impl.UserDaoImpl"></bean>
<!-- 设置为原型模式 -->
<bean id="userDao3" class="com.ying.dao.impl.UserDaoImpl" scope="prototype"></bean>
@Test
public void test04(){
//创建Spring容器对象 ApplicationContext
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl userDao3 = ac.getBean("userDao3", UserDaoImpl.class);
UserDaoImpl userDao4 = ac.getBean("userDao3", UserDaoImpl.class);
System.out.println(userDao3);
System.out.println(userDao4);
}
4.4 创建的对象三种方式
- 直接配置bean标签 id 对象的唯一标识 class 对象的全限定名
- 通过静态工厂来创建对象(了解)
- 通过非静态工厂来创建对象(了解)
静态工厂
<!-- 方式二:静态工厂 class:工厂类 factory-method:静态工厂方法-->
<bean id="userDao5" class="com.ying.factory.UserDaoFactory" factory-method="getUserDao1"/>
非静态工厂
<!-- 方式三:非静态工厂 factory-bean:工厂类的对象 factory-method:工厂非静态方法-->
<!-- 先创建工厂类的对象 -->
<bean id="factory" class="com.ying.factory.UserDaoFactory"></bean>
<bean id="userDao6" factory-bean="factory" factory-method="getUserDao2"></bean>
@Test
public void test05(){
//创建Spring容器对象 ApplicationContext
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl userDao4 = ac.getBean("userDao4", UserDaoImpl.class);
System.out.println(userDao4);
UserDaoImpl userDao5 = ac.getBean("userDao5", UserDaoImpl.class);
System.out.println(userDao5);
UserDaoImpl userDao6 = ac.getBean("userDao6", UserDaoImpl.class);
System.out.println(userDao6);
}
4.5 创建对象的生命周期
- SpringIOC容器创建Bean的生命周期
- 当创建的实例是单例模式:
- 当Spring容器创建的时候,对象就会被创建
- Spring容器关闭,就会销毁类的对象
- 当创建的实例是原型模式:
- Spring容器创建,并不会初始化,而是什么时候使用,什么时候初始化
- Spring容器创建,不会销毁类的对象。而是交给Java内存回收机制
属性配置
<bean id="userDao7" class="com.ying.dao.impl.UserDaoImpl"
scope="prototype" init-method="init" destroy-method="destroy">
</bean>
UserDaoImpl
public class UserDaoImpl implements UserDao {
@Override
public int addUser() {
System.out.println("UserDaoImpl添加。。");
return 0;
}
public void init(){
System.out.println("UserDaoImpl对象初始化");
}
public void destroy(){
System.out.println("UserDaoImpl对象销毁");
}
}
测试
@Test
public void test06(){
//创建Spring容器对象 ApplicationContext
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl userDao7 = ac.getBean("userDao7", UserDaoImpl.class);
System.out.println(userDao7);
//Spring容器关闭
ac.close();
}