Spring
Springframework 就是我们平时说的Spring框架,Spring框架是全家桶内其他框架的基础和核心
Spring以IoC(控制反转)和AOP(面向切面编程)为内核
控制反转IOC(Inverse of Control)
IoC是指将对象的创建权交给Spring容器去创建
由IoC容器管理的对象称为Spring Bean,Spring Bean就是Java对象
Spring通过IoC容器来管理对象的实例化和初始化,以及对象从创建到销毁的整个生命周期
Spring通过读取XML或Java注解中的信息来知道哪些对象需要实例化
Spring提供两种不同的IoC容器,即BeanFactory和ApplicationContext容器
2.1 定义Bean
在spring配置文件中定义一个bean:beans.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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="hw" class="com.st.HelloWorld" scope="singleton" lazy-init="false">
<!-- 指定属性值 -->
<property name="say" value="this is my first spring-demo!" />
</bean>
</beans>
示例(spring.xml中配置,注意beans内的网址是否对应)
<bean id="user" class="com.st.model.User" scope="singleton" lazy-init="false">
<constructor-arg index="0" name="student" ref="stu" />
<constructor-arg index="0" name="a" value="23" />
<constructor-arg index="1" name="b" value="ls"/>
</bean>
2.2 容器示例:ApplicationContext
//读取配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//根据配置文件中的id获取bean对象
HelloWorld obj = (HelloWorld) context.getBean("hw");
System.out.println(obj.getSay());
上面这种方式,只是为了演示IOC容器如何加载spring配置文件与如何获取bean对象;真正应用的框架中,只要在web.xml中做如下配置即可:
<!--指定Spring配置文件的位置,有多个配置文件时,以逗号分隔-->
<context-param>
<param-name>contextConfigLocation</param-name>
<!--spring将加载spring目录下的applicationContext.xml文件-->
<param-value>classpath:spring.xml</param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
2.3 < bean >元素的常用属性
属性名称 | 描述 |
---|---|
id | Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成。id 的值必须以字母开始,可以使用字母、数字、下划线等符号。 |
name | name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开。Spring 容器可以通过 name 属性配置和管理容器中的 Bean。 |
class | 该属性指定了 Bean 的具体实现类,它必须是一个完整的类名路径,即类的全限定名。 |
scope | 用于设定 Bean 实例的作用域,其默认值是 singleton |
constructor-arg | <bean> 元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type属性指定构造参数的类型,name属性指定参数名,value属性指定参数值 |
property | ``` |
ref | <property> 和 <constructor-arg> 等元素的子元素,用于指定对某个 Bean实例的引用 |
value | <property> 和 <constractor-arg> 等元素的子元素,指定一个属性值 |
init-method | 容器加载 Bean 时调用该方法,类似于 Servlet 中的 init() 方法 |
destroy-method | 容器删除 Bean 时调用该方法,类似于 Servlet 中的 destroy() 方法。该方法只在 scope=singleton 时有效 |
lazy-init | 懒加载,值为true,容器在首次请求对象时才会创建 Bean 实例;值为false,容器在启动时创建 Bean 实例。该属性只在scope=singleton时有效 |
2.4 bean的作用域:scope
Spring 容器在初始化一个 Bean 实例时,同时会指定该实例的作用域。
Spring 5 支持以下 6 种作用域:
singleton | 默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例,Bean 以单例的方式存在。 |
---|---|
prototype | 原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例。 |
request | 每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。 |
session | 同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。 |
application | 同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。类似于 singleton,不同的是,singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而同一个 Web 应用中可能会有多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。 |
websocket | websocket 的作用域是 WebSocket(一次socket连接),即在整个 WebSocket(一次连接的socket通信)中有效. |
2.6 IOC自动扫描
开启IOC自动扫描需要spring-context包的支持。
通过指定java类的包路径,IOC容器会自动扫描包路径下的所有被@Controller、@Service、 @Repository、@Component四个注解声明的类,并为其创建对象。
@Controller一般声明controller层的类
@Service一般声明Service层的类
@Repository一般声明dao层的类
@Component其他没有特殊要求的层用该注解修饰
示例:
<context:component-scan base-package="com.st.service"/>
2.5 bean的懒加载模式lazy-init
lazy-init懒加载
值为 true,容器在首次请求对象时才会创建 Bean 实例;
值为 false,容器在启动时创建 Bean 实例。
该属性只在 scope=singleton 时有效
3 依赖注入DI(Dependency Injection)
实现IOC思想需要DI做支持。
spring容器中,替你管理着一系列的通过IOC自动扫描到的类,这些类是交给spring容器进行管理的,在程序需要的时候,不是自己去定义,而是直接向spring容器索取,当spring容器知道你的需求之后,就会去它所管理的组件(beans)中进行查找,然后直接给你所需要的组件(bean对象)。
spring通过注解@Autowired和@Resource来完成java bean的注入。
示例:
@Autowired
private MyService myService;
3.1 @Autowired和@Resource的区别
通过@Resource或者@Autowired注解获取bean对象
@Autowired默认按类型注入
@Resource 默认根据变量名称(对象名)注入(即变量名称要与service别名一致),
当找不到与名称匹配的bean时才会按类型注入
IoC和DI
IoC叫控制反转,就是将创建的权利交给Spring容器
DI叫做依赖注入,从spring中获取对象
面向切面编程AOP(Aspect Oriented Programming)
定义:
AOP 的全称是“Aspect Oriented Programming”,译为“面向切面编程”,和 OOP(面向对象编程)类似,它也是一种编程思想。
AOP 是通过横向的抽取机制实现的。它将应用中的一些非业务的通用功能抽取出来单独维护,并通过声明的方式(例如配置文件、注解等)定义这些功能要以何种方式作用在哪个应用中,而不是在业务模块的代码中直接调用。常见的AOP应用场景有:日志、事务等
作用:
AOP 用来封装多个类的公共行为,将那些与业务无关,却被业务模块所共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP 还解决一些系统层面上的问题,比如日志、事务、权限等。
使用aop需要引入spring-aop包。
spring.xml beans标签内配置
<!-- 配置AOP切面类bean,目的是实现IoC,让Spring容器创建类对象 -->
<bean name="aop_util" class="com.st.util.AopUtil"></bean>
<!-- AOP配置 -->
<aop:config>
<!-- 定义切面类 -->
<!-- ref 关联jave bean的name属性-->
<aop:aspect id="myAspect" ref="aop_util">
<!-- 定义切入点: 切面类的代码将要插入的位置上
execution(* com.st.service.*.get*(..)
第一个* 表示任意权限private、public等
第二个* 表示com.st.service包下任意类
第三个* 表示该类的任意以get开头的方法
(..) 表示任意个数的参数列表
-->
<aop:pointcut id="myPointCut" expression="execution(* com.st.service.*.get*(..))"/>
<!-- 定义通知:定义切面类的代码与切入点的相对位置
1前置通知 before
2后置通知 after-returning
3异常通知 after-throwing
4最终通知 after
5环绕通知 around
-->
<!--
pointcut-ref 关联切入点
method 切面类-切入的方法
-->
<!-- 前置通知 -->
<!-- <aop:before pointcut-ref="myPointCut" method="speak"/>-->
<!-- 环绕通知 -->
<aop:around pointcut-ref="myPointCut" method="speakAround"/>
</aop:aspect>
</aop:config>
5 spirng框架依赖jar包
名称 | 作用 |
---|---|
spring-core-x.x.xx.RELEASE.jar | 包含 Spring 框架基本的核心工具类,Spring其他组件都要用到这个包中的类,是其他组件的基本核心。 |
spring-beans-x.x.xx.RELEASE.jar | 所有应用都要用到的,它包含访问配置文件、创建和管理Bean以及进行 Inversion of Control(IoC)或者 Dependency Injection(DI)操作相关的所有类。 |
spring-context-x.x.xx.RELEASE.jar | 提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI 定位、EJB 集成、远程访问、缓存以及各种视图层框架的封装等 |
spring-expression-x.x.xx.RELEASE.jar | 定义了 Spring 的表达式语言。需要注意的是,在使用 Spring 开发时,除了 Spring 自带的 JAR 包以外,还需要一个第三方 JAR 包 commons.logging 处理日志信息 |
commons-logging-1.2.jar | Common Logging 是使用 Spring 的必要组件 |
spring-tx-x.x.xx.RELEASE.jar | 提供Spirng事务相关服务 |