Spring(IOC/AOP/声明式事务)
2021-02-06 15:45:26 39 举报
AI智能生成
Spring
作者其他创作
大纲/内容
IoC
把对象的创建和调用的过程交给Spring管理
目的:降低耦合度
IoC底层原理
xml解析
从xml配置文件中获取类的全路径名
<bean id="userDao" class="com.cherry.UserDao"/>
<bean id="userDao" class="com.cherry.UserDao"/>
反射
利用反射机制创建对象
Class clazz = Class.forName("类的全路径名");
clazz.newInstance();
工厂模式
将对象返回(IOC容器的底层就是对象工厂)
重要接口
BeanFactory
Spring内部的使用接口,不提供开发人员使用
加载配置文件时不会创建对象,在获取(使用)对象时才创建
ApplicationContext
BeanFactory的子接口,提供更多更强大的功能(常用)
加载配置文件时会创建配置文件中的对象(耗时耗资源的过程在启动的时候加载)
实现类
FileSystemXmlApplicationContext:磁盘中的类路径
ClassPathXmlAplicationContext:classpath下的类路径
AnnotationConfigApplicationContext:加载配置类@Configuration
Spring中使用的设计模式
单例模式
Bean默认为单例模式
工厂模式
BeanFactory就是简单工厂模式的体现,用来创建对象的实例
代理模式
Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
模版方法
用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
观察者模式
Spring中listener的实现ApplicationListener
Bean管理
Bean的装配
基于xml
创建对象
使用bean标签,指定id和class(默认使用无参构造)
注入属性(DI)
set方法注入
有参构造器注入
p名称空间注入(了解)
其他类型
字面量(固定值)
注入null值:<null/>
注入特殊符号:转义或使用<![CDATA[...]]>
外部Bean作为属性注入
ref
内部Bean和级联赋值
一对多关系:ref或Bean标签嵌套
集合属性
array、list、map、set
基于注解
目的:简化xml配置
创建对象
@Component、@Controller、@Service、@Repository
记得开启注解和组件扫描
注入属性
@Autowired、@Qualifier、@Resource、@Value
自动装配
根据指定的装配规则(属性名称或类型),Spring自动将匹配的属性值进行注入的过程
基于xml
autowired属性:no、byName、byType、constructor、autodetect
基于注解
@Autowired默认byType,找不到再byName,@Resource相反
作用域
scope属性
singleton:必须返回同一个实例
prototype:每次生产一个新的 bean 实例
request、session、application(了解)
区别?
Bean对象的创建时机不同,singleton加载时创建,protorype使用时才创建
Spring 框架中的单例 bean 是线程安全的吗?
不是线程安全的,存在共享变量时在多线程下会出现线程安全问题
Spring使用ThreadLocal解决线程安全问题
生命周期
一句话:对象从创建到销毁的过程
过程
1、通过构造器创建bean实例(默认无参构造)
2、为bean的属性设置值或引用其他bean(调用set方法)
3、在bean初始化之前把bean实例传递给后置处理器的postProcessBeforeInitialization()方法
4、调用bean的初始化方法(两种配置方式)
在配置文件中通过指定 init-method 属性来完成
实现 org.springframwork.beans.factory.InitializingBean 接口
5、在bean初始化之后把bean实例传递给后置处理器的postProcessAfterInitialization()方法
6、获取并使用bean
7、当容器关闭的时候,调用bean的销毁方法(两种配置方式)
使用配置文件指定的 destroy-method 属性
实现 org.springframwork.bean.factory.DisposeableBean 接口
常见问题
普通Bean和工厂Bean的区别?
在配置文件中定义的Bean类型就是普通Bean的返回类型
工厂Bean的返回类型可以和定义类型不同
BeanFactory和FactoryBean的区别?
BeanFactory是一个接口,它是Spring中工厂的顶层规范,
它的实现类有ApplicationContext,是IoC容器的核心接口
它的实现类有ApplicationContext,是IoC容器的核心接口
FactoryBean是一个能生产或修饰对象生成的工厂Bean,
它能在需要的时候生产一个对象,返回任何的Bean实例
它能在需要的时候生产一个对象,返回任何的Bean实例
Spring如何解决循环依赖?
首先要理解什么是循环依赖,比如类A的创建依赖引用B,类B的实例化又依赖类A
Spring的实例化是分步进行的,首先创建目标对象,然后为其注入属性
Spring解决循环依赖使用了三级缓存,三级缓存发生在创建对象后注入属性前
Spring在为目标对象注入属性前先在map中缓存半成品bean,递归注入
Spring的Controller是单例吗?
controller默认是单例的,不保证线程安全,会导致其属性被重复使用
解决
不要在controller中定义成员变量
可以通过@Scope("prototype")将其设置为多例模式
在controller中使用ThreadLocal
AOP
面向切面编程
目的:在不修改原代码的前提下,把新功能织入到程序中
底层原理:动态代理
有无接口
有接口使用jdk动态代理
没有接口使用cglib动态代理
静态代理和动态代理的区别?
静态代理每次增强都会创建一个新类,代码非常臃肿
静态代理在代理前就知道要代理的对象,动态代理运行时才知道
静态代理一般只能代理一个类,动态代理能代理实现了接口的多个类
jdk动态代理和cglib动态代理的区别?
jdk动态代理不需要引入第三方包,要求被代理对象必须实现接口
cglib动态代理需要引入第三方包,被代理对象实现不实现接口都可以
cglib动态代理需要引入第三方包,被代理对象实现不实现接口都可以
cglib采用字节码技术,为一个类创建一个子类(代理对象),
在子类中采用方法拦截的技术拦截所有父类方法的调用
在子类中采用方法拦截的技术拦截所有父类方法的调用
1.8以前cglib的性能会高一些,1.8之后性能差不多
术语
连接点
类中可以被增强的方法
切入点
实际被增强的方法,称为切入点
表达式
execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
举例:execution(* com.cherry.dao.BookDao.*(..))
通知类型(增强)
前置增强、后置增强、环绕增强、异常增强(after-throwing)、最终增强(after-returning)
切面
把增强代码应用到切入点的过程
实现
原生API
AspectJ
独立的AOP框架,以Aspectj编程风格实现AOP
基于配置文件
创建切面类,在类中定义不同增强类型的方法(before、after)
在配置文件中添加<aop:config>标签,声明<aop:pointcut、aspect、before>等
基于注解
开启aspectj和注解扫描
基于xml
<context:component-scan base-package="..."/>
<aop:aspectj-autoproxy/>
基于注解
@ComponentScan(basePackages="...")
@EnableAspectJAutoProxy(proxyTargetClass=true)
@Aspect+@Component:标记增强类,注册到IoC容器
@Before、@After…标记增强类型(结合execution)
@Pointcut结合execution,抽取相同切入点
@Order(1):标记增强类的优先级,数值越小优先级越高
应用
权限控制
日志管理
事务
事务
事务是一组操作,要么都成功,要么都失败
声明式事务底层原理:AOP
四个特性(ACID)
原子性、一致性、隔离性、持久性
类型
编程式事务
手动编写提交回滚逻辑
对业务代码有侵入性
声明式事务
基于xml配置
基于注解
配置事务管理器,开启事务注解
在service类或方法上添加@Transactional注解
@Transactional(参数说明)
propagation:传播行为(7种)
REQUIRED(默认)
如果当前存在事务,则加入该事务;
如果当前不存在事务,则新建事务
如果当前不存在事务,则新建事务
REQUIRED_NEW
新建事务执行,如果当前已经在事务
中,则把当前事务挂起
中,则把当前事务挂起
SUPPORTS、NOT_SUPPORTS、MANDATORY、NEVER、NESTED
isolation:隔离级别
如果连接mysql数据库,默认是可重复读
相比mysql数据库多一个default
timeout:超时时间
事务需要在一定的时间内进行提交,否则回滚
默认是-1,没有超时时间,可自定义值,单位是秒
readOnly:是否只读
默认是false,可查询,可修改
修改为true,则只支持查询功能
rollbackFor:回滚
设置出现哪些异常进行事务回滚
noRollbackFor:不回滚
设置出现哪些异常不进行事务回滚
Spring5新特性
整个Spring5框架的代码基于Java8,运行时兼容JDK9
Spring5自带了通用的日志封装
log4j2
Spring5核心容器支持@Nullable注解
标注在方法上,表示方法的返回值可以为空
标注在方法的参数上,表示该参数可以传空值
标注在属性上,表示该属性值可以为空
支持函数式风格创建对象
支持整合JUnit5
Spring WebFlux
概念
Spring5添加的新模块,用于web开发,功能与SpringMVC类似,
WebFlux使用当前一种比较流行的【响应式编程】而出现的框架
WebFlux使用当前一种比较流行的【响应式编程】而出现的框架
响应式编程是一种面向数据流和变化传播的编程范式(观察者模式)
特点
异步非阻塞:在有限资源下提高系统吞吐量和伸缩性,基于Reactor实现
函数式编程:Webflux使用Java8函数式编程方式实现路由请求
对比SpringMVC
两个框架都支持注解的方式,都运行在Tomcat容器中
SpringMVC采用命令式编程,WebFlux采用异步响应式编程
待续
扩展
同步和异步(针对调用者)
调用者发送请求,如果等着对方回应之后才去做其他事情就是同步
如果发送请求之后不等待对方回应就去做其他事情就是异步
如果发送请求之后不等待对方回应就去做其他事情就是异步
阻塞和非阻塞(针对被调用者)
被调用者收到请求后,做完请求任务后才给出反馈就是阻塞,
收到请求之后马上给出反馈然后再去做事情就是非阻塞
收到请求之后马上给出反馈然后再去做事情就是非阻塞
0 条评论
下一页