Spring框架概念
- Spring是一个轻量级的开源的JavaEE框架
- 解决企业应用开发的复杂性
- Spring两个核心部分:IOC和AOP
Spring入门实例
搭建好Spring基本框架(只导入4个基础包),使用配置文件和注解调用创建的类以及调用成员方法。
-
1.创建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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置User对象创建--> <bean id="user" class="com.mm.spring5.User"></bean> </beans>
-
2.进行测试代码编写
package com.mm.spring5.testDemo; import com.mm.spring5.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { @Test public void testUser(){ //加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //通过getBean()方法获取对象的实例 User user = context.getBean("user",User.class); user.add(); } }
Spring IOC简介
IOC(Inversion of Control):控制反转,是Spring Core最核心的部分。更确切的说是一种思想,将我们从繁琐的对象交互中解脱,进而专注于对象本身。
含义:把底层类作为参数传递给上层类,实现上层对下层的“控制”
方式:
依赖注入(Dependency Injection)方式,主流使用
1.构造函数(Constructor),实现特定参数的构造函数,在创建对象时将底层类作为参数传递给上层类,让IOC容器注入所依赖的类型的对象
2.Set注入(Setter),实现特定属性的public set()方法来让IOC容器调用注入所依赖的类型的对象
3.接口注入(Interface),实现特定的接口以供IOC容器注入所依赖的类型的对象
4.注解注入(Annotation),通过java的注解机制,让IOC容器注入所依赖的类型的对象。例如,Sprint框架里的AutoWired这一类的标签,能够实现注解功能。
Dependency Lookup方式,被放弃使用
IOC底层原理
IOC思想离不开依赖注入(DI)方法,基于IOC思想提出了IOC容器。IOC容器管理bean的生命周期,控制bean的依赖注入。
- xml解析
- 工厂模式,降低耦合度
- Java反射机制,得到类的class文件,使用其属性和方法
IOC容器的优势
- 使用依赖注入会进行大量new操作,IOC容器可以自动对代码进行初始化,只需维护一个config文件,例如xml文件即可。避免在各处使用new来创建类,并且可以做到统一维护依赖关系
- 创建实例时不需要了解其细节,我们只需请求一个对象(很多类作为该对象类的底层)的实例,IOC容器按照Config文件创建一个该对象的实例。
Spring IOC应用
- Spring启动时,读取应用程序提供的Bean配置信息,并在Spring容器中生成一份Bean的注册表
- 根据注册表实例化Bean,Spring提供一个配置文件描述Bean和Bean之间的依赖关系,利用Java的反射功能实例化Bean。
- 将Bean实例放到Spring容器的Bean缓存池中
- 使用Bean,装配好Bean之间的依赖关系,为上层提供准备就绪的运行环境。<img
SpringIOC容器的接口
核心接口(IOC容器的两种实现方式):
-
BeanFactory
-
加载配置文件时,不会创建对象,只有在使用对象时才会创建(懒加载机制)
-
包含Bean的各种定义,便于实例化Bean
-
建立Bean之间的依赖关系
-
Bean生命周期的控制
-
Spring框架的基础设施,Spring内部的使用接口,面向Spring
-
主要方法
-
getBean(),从Spring容器中获取Bean
-
isSingleton(),Bean在容器中是否是单例,默认是单例
-
-
-
ApplicationContext
- 加载配置文件时,对象就会创建
- 面向Spring框架的开发者
- 继承了BeanFactory,能够管理、装配Bean
- ResourcePatternResolver,能够加载资源文件
- MessageSource,能够实现国际化等功能
- ApplicationEventPublisher,能够注册监听器,实现监听机制
主要接口:
- BeanDefinition,主要描述Bean的定义
- BeanDefinitionRegistry,提供向IOC容器注册BeanDefinition对象的方法
Spring IOC支持的功能
-
依赖注入
外部注入bean的三种方式:
- set()方法
- 构造器
- 属性反射(AutoWired)
-
自动装配
-
依赖检查
-
支持集合
-
指定初始化方法和销毁方法
-
支持回调方法
IOC操作Bean管理
**什么是Bean管理?**Bean管理指的是两个操作
- Spring创建对象
- Spring注入属性
Bean管理操作两种实现方式
-
基于xml配置文件方式,在Spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象创建、属性注入。
1.创建对象
-
bean标签的常用属性:
-
id,对象起的唯一别名、标识
-
class,类全路径
-
property,属性
-
-
创建对象时,默认调用的是无参构造器
2.注入属性
-
使用set()方法进行注入,需要在类中实现set()方法
<bean id="user" class="com.mm.spring5.User"> <property name="userName" value="mm"></property> </bean>
-
使用有参数构造器注入
<bean id="order" class="com.mm.spring5.Order"> <constructor-arg name="oName" value="abc"></constructor-arg> <constructor-arg name="address" value="china"></constructor-arg> </bean>
3.xml注入其他类型属性
-
null值
<property name="content"> <null/> </property>
4.注入外部bean
<bean id="userService" class="com.mm.spring5.service.UserService"> <property name="userDao" ref="userDaoImpl"></property> </bean> <bean id="userDaoImpl" class="com.mm.spring5.dao.UserDaoImpl"></bean>
-
-
基于注解方式
getBean原理
- 转换beanName
- 从缓存中加载实例
- 实例化Bean
- 检测parentBeanFactory
- 初始化依赖的Bean
- 创建Bean
Spring实例
目的:
- Bean如何装载到IOC容器中
- 如何从IOC容器获取Bean实例、使用Bean实例
- 分析ICO容器的创建配置以及Bean如何获取的底层原理
方法:
- 使用@Bean装配Bean,效率不高
- 通过run()获取ApplicationContext的实例ctx
- 调用ctx的getBean()方法获取Bean
- 使用SpringBoot方式,扫描并装配Bean到IOC容器,在装载类上加上@Componet,表明哪个类需要被扫描到SpringIOC容器中
- 类里面的成员变量若为类对象,需要使用@Autowired进行注释,根据属性类型找到对应的Bean进行注入。注入机制最重要的一条就是根据类型,通过BeanFactory接口,IOC容器通过getBean()方法,支持根据类型、名称来获取Bean。
Spring相关面试题
-
Spring Bean的作用域?
- singleton,Spring的默认作用域,容器里拥有唯一的Bean实例
- protitype,针对每个getBean请求,容器都会创建一个Bean实例
- request,会为每个Http请求创建一个Bean实例
- session,会为每个session创建一个Bean实例
- globalSession,会为每个全局Http Session创建一个Bean实例,该作用域仅对Portlet有效
-
Spring Bean的生命周期?由SpringIOC容器进行管理
-
Bean的创建
-
实例化Bean对象,在BeanDefinition类中设置Bean属性
(通过ware注入Bean对容器基础设施层面的依赖,对实例化完成的Bean添加自定义的处理逻辑)
-
使用BeanDefinitionRegistry注册BeanDefinition,建立映射
-
调用定制的Bean init方法,进行初始化相关的操作
-
Bean实例初始化之后的自定义工作
-
Bean初始化完毕
-
-
Bean的运行
- 在应用程序中使用通过getBean()方法获取并使用Bean
-
Bean的销毁
- 当Bean不在被使用时,就会进入销毁阶段
- 调用实现接口或配置属性的销毁方法
-
Spring AOP
面向切面编程。
思想:
- 关注点分离,不同的问题交给不同的部分去解决
- 通用化功能代码的实现,对应的就是所谓的切面(Aspect)
- 业务功能代码和切面代码分开,架构将变得高内聚低耦合
- 确保功能的完整性,切面最终需要被合并(织入)到业务中(Weave)
AOP的主要名称概念
- Aspect,通用功能的代码实现(例如日志切面,就是一个普通的java类实现日志记录功能 )
- Target,目标对象,即被织入Aspect的对象()
- Join Point,可以作为切入点的机会,所有的方法都的执行处可以作为切入点(例如HelloWorld的请求方法)
- Pointcut,Aspect实际被应用在Join Point,支持正则。Pointcut定义Join Point应该切入到哪个地方。
- Advice,类里面的方法以及这个方法如何织入到目标方法的方式
- 前置通知(Before)
- 后置通知(AfterReturning)
- 异常通知(AfterThrowing)
- 最终通知(After)
- 环绕通知(Around)
- Weaving,
- 编译时织入
- 类加载时织入
- 运行时织入,Spring采用的方式,通过动态代理的方式,实现简单
实例之日志记录
- 目的:记录访问的ip、时间、返回值等
- 流程:
- What,将记录日志的功能代码分离出来,做成一个切面,在切面中解决What的内容,即实现日志功能(Aspect)
- Where,Target目标对象,需要使用该切面功能的类对象。Pointcut可使用正则确定切入点,什么类型的方法可以作为切入点。
- When,确定什么时候进行织入,即调用目标对象中的方法之前还是之后还是其他时候进行
Spring AOP的原理
Spring事务的相关考点
-
ACID
-
隔离级别
-
事务传播