Spring框架(一)

mac2026-06-10  21

什么是Spring?

Spring是 分层 的轻量级开源框架Spring核心是IOC(控制反转) 和 AOP(面向切面编程)Spring提供了对各种优秀框架的支持和 整合

Spring优点

IOC解耦 可以将对象间的依赖关系交由spring管理避免硬编码造成的程序间过渡耦合 支持AOP 可以使用切面编程思想对方法进行增强 支持声明式事务 可以通过配置或者注解的方式管理事务不需要硬编码管理事务 方便测试 可以通过注解方便的测试Spring程序 方便集成 其内部提供了对各种优秀框架的直接支持 使用简单 Spring对很多难用的API做了简单的封装 设计精良 Spring的源码设计精妙、结构清晰值得学习

不使用Spring会有什么影响

会造成(常见的):

依赖问题耦合问题 (1 )实现类丢失会影响其他层 ( 2)实现类切换会影响其他层创建顺序对象个数

Spring结构

Spring框架采用分层架构,根据不同的功能被划分成了多个模块

Data Access/Integration

JDBC: 对各大数据库厂商进行抽象处理ORM: 集成orm框架支持对象关系映射处理OXM: 提供了对 Object/XML映射实现的抽象层JMS: 主要包含了一些制造和消费消息的特性Transactions: 支持编程和声明式事务管理

Web

Websocket: 提供了WebSocket和SocketJS的实现Servlet: 利用MVC(model-view-controller)的实现分离代码Web: 提供了基础的面向 Web 的集成特性(如: 文件上传)Portlet: 提供了Portlet环境下的MVC实现

中间层

AOP: 提供了符合AOP要求的面向切面的编程实现Aspects: 提供了与AspectJ的集成功能Instrumentation: 提供了类植入(Instrumentation)的支持和类加载器的实现Messaging: 用于构建基于消息的应用程序

Core Container

Beans: Bean工厂与bean的装配Core: 依赖注入IoC与DI的最基本实现Content: IOC容器的企业服务扩展SpEl: 用于在运行时查询和操纵对象的表达式

Test

支持使用 JUnit 和 TestNG 对 Spring 组件进行测试

IOC容器

IOC是什么?

IOC(Inversion Of Control): 将对象的创建(控制)转交给第三方(工厂)完成, 也叫 控制反转

IOC的作用?
解耦: 利用IOC的工厂模式解耦创建对象的过程 解决代码耦合度过高问题 存储对象: 可以将创建好的对象 存储 起来重复使用 解决对象个数问题 管理依赖关系: 可以将依赖对象注入需要的对象当中 解决依赖关系问题 管理对象创建顺序: 可以根据依赖关系先后创建对象 解决创建顺序问题

bean标签的属性

属性说明id对象的引用名称;一定要唯一; 一次只能定义一个引用名称name对象的引用名称; 与id区别是:name一次可以定义多个引用名称。class类的全限定名称init-method指定类中初始化方法的名称,在构造方法执行完毕后立即执行destroy-method指定类中销毁方法名称,在销毁spring容器前执行lazy-init设置为true表示在第一次使用对象的时候才创建,只对单例对象有效。scope设置bean的作用范围, 取值:singleton:单例, 默认值; prototype:多例 request:web项目中,将对象存入request域中session:web项目中,将对象存入session域中globalsession:web项目中,将对象应用于集群环境,没有集群相当于session BeanFactory是Spring容器的顶层接口, 采用 延迟创建 对象的思想ApplicationContext是BeanFactory的子接口, 采用 即时创建 对象的思想

Bean-作用范围

<!-- scope: 设置对象的作用范围 singleton: 默认值, 表示为单例模式: 对象只创建一次 prototype: 多例模式, 标识对象每次使用都创建一个新的 (并且不会将对象存储到IOC容器中) --> <bean init-method="init" destroy-method="destroy" scope="prototype" class="com.itheima.xml.User"/>

依赖注入

什么是依赖注入?

Spring提供的给对象赋值的功能

代码演示:

创建实体类Person public class Person { private Integer id; private String name; //省略构造、有参无参、tostring } 配置注入: beans.xml <!-- constructor-arg: 调用构造方法注入参数、属性值 name: 属性名称 value: 注入的值 --> <bean class="com.itheima.xml.Person"> <constructor-arg name="id" value="2"/> <constructor-arg name="name" value="Jason2"/> </bean>
set方法赋值
<!-- property: 调用set方法注入参数/属性值 name: 属性名称 value: 注入的值 --> <bean class="com.itheima.xml.Person"> <property name="id" value="1"/> <property name="name" value="Jason"/> </bean>
C标签代替构造方法
引入C名称空间 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- c标签命名空间 --> xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 使用c标签 <!-- c:_0: 表示给指定参数列表的下标参数注入值 c:name: 指定参数列表中的参数名称注入值 --> <bean class="com.itheima.xml.Person" c:_0="3" c:name="Jason3"/>
P标签代替set方法
引入P名称空间 <?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:c="http://www.springframework.org/schema/c" <!-- p标签命名空间 --> xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 使用p标签 <!-- p:id: 指定参数名称注入值 p:name: 指定参数名称注入值 --> <bean class="com.itheima.xml.Person" p:id="4" p:name="Jason4"/>

注入对象

配置需要注入的对象 <!-- 定义了对象 --> <bean id="str" class="java.lang.String"> <constructor-arg index="0" value="Jason5"/> </bean> 注入bean对象属性值 <!-- ref: 引用一个已经存在的对象 --> <bean class="com.itheima.xml.Person"> <property name="name" ref="str"/> </bean>

基于注解创建对象

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itheima</groupId> <artifactId>spring01_anno_04</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- 1. 添加SpringIOC依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- 2. 添加JUnit依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>

创建实体类

/** * @Component: 修饰类 * 作用: 创建对象并且加入到IOC容器中 : 相当于代替了bean标签 * value: 对象的名称 * @Repository: 修饰类. 一般用于修饰持久层的类 * @Service: 修饰类. 一般用于修饰业务层的类 * @Controller: 修饰类. 一般用于修饰视图层的类 * 作用: 创建对象并且加入到IOC容器中 : 相当于代替了bean标签 * value: 对象的名称: 默认名称是首字母小写的类名account */ @Component(/*"account"*/) public class Account { private Integer id; private Integer uid; private Double money; }

添加配置: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"> <!-- 1. 添加Spring组件扫描配置 base-package: 指定扫描的路径 --> <context:component-scan base-package="com.itheima.anno"/> </beans>

测试:

@Test public void testComponent (){ // 1. 创建IOC容器 ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml"); // 2. 使用对象 Account account = (Account) ioc.getBean("account"); System.out.println(account); }

依赖注入的注解

创建实体: /** * 用户类. * * @author : Jason.lee * @version : 1.0 */ @Component public class User { private Integer id; /** * @Autowired: 修饰属性和方法 * 作用: 可以注入一个已经存在的对象 (代替了ref属性) * * 可以根据属性名称+类型注入参数值 * @Qualifier: 修饰属性和方法,参数列表 * 一般与@Autowired配合使用 * 作用: 【只】根据容器中的对象名称注入参数值 * @Resource: 修饰属性和方法 【jdk1.8之后已经去除】 * 作用: 相当于@Autowired+@Qualifier */ // @Autowired // @Qualifier("username1") @Resource(name = "username1") private String username; private Date birthday; private String sex; /** * @Value: 修饰属性 * 作用: 注入一个固定的参数值: */ @Value("江西") private String address; 配置对象: 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"> <!-- 1. 添加Spring组件扫描配置 base-package: 指定扫描的路径 --> <context:component-scan base-package="com.itheima.anno"/> <bean id="username2" class="java.lang.String"> <constructor-arg index="0" value="Jason9"/> </bean> <bean id="username1" class="java.lang.String"> <constructor-arg index="0" value="Jason"/> </bean> </beans> 测试 @Test public void testDi (){ // 1. 创建IOC容器 ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml"); // 2. 使用对象 User account = ioc.getBean(User.class); System.out.println(account); }

注解和配置的关系图

注解是配置的代替方案 (是配置的一种) 配置方式 (常用)注解方式 (常用)Bean定义@ComponentBean名称bean标签的id或name属性@Component的value值Bean注入bean标签的子标签<property…@Autowired(1) + @Qualifier (?)Bean生命周期bean标签的init- | destroy- method属性@PostConstruct | @PreDestroyBean延迟创建bean标签的lazy-init | scope 属性@Lazy | @Scope适用场景第三方源码类的对象创建自定义类的简单应用对象创建 注解的优势: 简单, 可读性高 (找到类就相当于找到配置)配置的优势: 解耦, 非侵入性 (代码与配置分开互不干扰)
最新回复(0)