什么是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-作用范围
<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
;
}
配置注入: beans.xml
<bean class="com.itheima.xml.Person">
<constructor-arg name="id" value="2"/>
<constructor-arg name="name" value="Jason2"/>
</bean>
set方法赋值
<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标签
<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标签
<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对象属性值
<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>
<dependency>
<groupId>org.springframework
</groupId>
<artifactId>spring-context
</artifactId>
<version>5.0.2.RELEASE
</version>
</dependency>
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.12
</version>
</dependency>
</dependencies>
</project>
创建实体类
@Component()
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">
<context:component-scan base-package="com.itheima.anno"/>
</beans>
测试:
@Test
public void testComponent
(){
ClassPathXmlApplicationContext ioc
= new ClassPathXmlApplicationContext("applicationContext.xml");
Account account
= (Account
) ioc
.getBean("account");
System
.out
.println(account
);
}
依赖注入的注解
创建实体:
@Component
public class User {
private Integer id
;
@Resource(name
= "username1")
private String username
;
private Date birthday
;
private String sex
;
@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">
<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
(){
ClassPathXmlApplicationContext ioc
= new ClassPathXmlApplicationContext("applicationContext.xml");
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适用场景第三方源码类的对象创建自定义类的简单应用对象创建
注解的优势: 简单, 可读性高 (找到类就相当于找到配置)配置的优势: 解耦, 非侵入性 (代码与配置分开互不干扰)