Spring
Spring
分层解耦
- 内聚:软件中各个功能模块内部的功能联系。
- 耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
- 软件设计原则:高内聚低耦合。
三层架构
- controller:表现层,接收前端发送的请求,对请求进行处理,并响应数据。
- service:业务逻辑层,处理具体的业务逻辑。
- dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增、删、改、查。
控制反转
- 控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(IOC容器),这种思想称为控制反转(使用对象时,由主动new产生对象转换为由外部提供对象)。
- 加上@Component注解,即可将当前类交给IOC容器管理,成为IOC容器中的bean
- @Componnent的衍生注解,因为@Component往往不会用在三层架构上。
- @Controller:标注在控制器类(Controller层)上
- @Service::标注在业务类(Service层)上
- @Repository:标注在数据访问类上(Dao层)上
- 注意
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器(Controller层)bean只能用@Controller。因为Controller层的@RestController=@Controller+@ResponseBody。
依赖注入
依赖注入:Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
- 加上@Autowired注解,运行时,IOC容器会提供该类型的bean对象,并赋值给该变量–依赖注入
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报错误,解决方案
- @Primary注解:在对应的bean类上加上,即可指定优先级更高
- @Qualifier注解:通过@Autowired注解和@Qualifier注解(“指定bean名”)指定注入哪个bean
- @Resource注解 :不用@Autowired注解而是改成@Resource注解(name=“指定bean名”)
Bean
- Bean对象:IOC容器中创建、管理的对象,称之为bean。
- Bean组件扫描
- 默认扫描的范围是启动类所在包及其子包。
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 主动获取bean,通过AplicationContext IOC容器对象中的方法
- 根据名称获取:Object getBean(String name)
- 根据类型获取:<T> T getBean(Class<T> requiredType)
- 根据名称和类型获取:<T> T getBean(String name , Class<T> requiredType)
bean作用域
可以通过@Scope(“作用域”)来配置作用域
singletion:容器内同名称的bean只有一个实例(单例)(默认)
prototype:每次使用该bean时会创建新的实例(非单例)
request:每个请求范围内会创建新的实例(web环境中,了解)
session:每个会话范围内会创建新的实例(web环境中,了解)
application:每个应用范围内会创建新的实例( web环境中,了解)
注意
- 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)。
- prototype的bean,每一次使用该bean的时候都会创建一个新的实例。
- 实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。
第三方bean
- 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component及衍生注解声明bean的,就需要用到@Bean注解。
- @Bean是加在方法上的,不是类名上
- 若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过@Configuration注解声明一个配置类。
- 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。
- 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。
AOP
AOP基本概念
什么是AOP
- AOP就是面向切面编程,其实就是面向特定方法编程。
作用
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而是的业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
使用场景
- 记录操作日志、权限控制、事务管理等
实现原理
- 动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。
专业术语
- 切入点:PointCut,被AOP控制的匹配连接点的条件,通知仅会在切入点方法执行时被应用
- 连接点:JoinPoint,可以被AOP控制的方法。
- 通知:Advice,指哪些重复的逻辑,也就是共性功能,切面必须要完成的工作。(最终体现为一个方法)
- 切面:Aspect,描述通知与切入点的对应关系(通知+切入点)
- 目标对象:Target,通知所应用的对象
- AOP最终执行的并非是原始的目标对象,而是基于目标对象自动生成的代理对象。
- 拿切西瓜来说
- 连接点就是西瓜的任何地方
- 切入点表达式就是切西瓜的规则(例如只在西瓜的中间切)
- 切入点是真正被切的地方
- 通知是切西瓜前后的动作,比如切西瓜前的拿刀、切西瓜后的放刀。
- 切面可以是切西瓜的整个过程
通知方法
- @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
- @Around环绕通知需要自己调用ProceedingJoinPoint.proceed()来让原始方法执行,其他通知不需要考虑目标方法执行
- @Around环绕通知方法的返回值,必须指定为0bject,来接收原始方法的返回值。
- @Before:前置通知,此注解标注的通知方法在目标方法前被执行
- @After:后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执
- @AfterReturning:返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执
- @AfterThrowing:异常后通知,此注解标注的通知方法发生异常后执行
步骤
- 导入AOP依赖
- 定义通知类@Aspect,并将该类交给IOC容器管理(@Component)
- 定义通知方法(方法里面实现共性功能)
- 定义切入点@Pointcut(切入点表达式)和其依托的方法(切入点定义依托一个不具有实际意义的方法进行,即无参数,无返回值,方法体无实际逻辑)
- 绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置(通知方法)
- 切入点表达式可以写在通知方法里面,这样第四步就可以省略了
- 开启Spring对AOP注解驱动支持(@EnableAspectJAutoProxy)
- 在springboot项目里面,可以省略第六步
通知顺序
- 当有多个切面的切入点都匹配到了目标方法,目标方法运行时,多个通知方法都会被执行。
执行顺序
- 不同切面类中,默认按照切面类的类名字母排序:
- 目标方法前的通知方法:字母排名靠前的先执行
- 目标方法后的通知方法:字母排名靠前的后执行
- 用@Order(数字)加在切面类上来控制顺序
- 目标方法前的通知方法:数字小的先执行
- 目标方法后的通知方法:数字小的后执行
切入点表达式
- 切入点表达式:描述切入点方法的一种表达式
- 作用:主要用来决定项目中的哪些方法需要加入通知
execution
- execution主要根据方法的返回值、包名、类名、方法名、方法参数等信息来匹配
- 语法:execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数的全类名) 异常?)
- 其中带?的部分可以省略
- 注意,异常是方法上声明抛出的异常,不是实际抛出的异常
- 通配符
- *:单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分
- ..:多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数
- 根据业务需要,可以使用且(&&)、或()、非(!)来组合比较复杂的切入点表达式。
@annotation
- @annotation切入点表达式,用于匹配标识有特定注解的方法。
- 特定注解是自己定义的
- 语法:@annotation(注解全类名)
事务管理
- 概念:事务是一组操作的集合,它是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败。
- 操作
- 开启事务(一组操作开始前,开启事务) : start transaction / begin ;
- 提交事务(这组操作全部成功后,提交事务): commit ;
- 回滚事务(中间任何一个操作出现异常,回滚事务) : rollback ;
spring事务管理
注解:@Transactional
- 位置:业务( service)层的方法上、类上、接口上
- 作用∶将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务
- 注意
- 默认情况下,只有出现RuntimeException 才回滚异常.
spring事务管理日志开关
1
2
3
4#开启spring事务管理日志开关
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug@Transactional的属性
- rollbackFor:用于控制出现何种异常类型,回滚事务。
- 如:@Transactional(rollbackFor = Exception.class),所有异常都会回滚事务
- propagation:可以控制事务的传播行为,其常用属性值如下
- REQUIRED:【默认值】需要事务,有则加入,无则创建新事务
- REQUIRES_NEW:需要新事务,无论有无,总是创建新事务
- rollbackFor:用于控制出现何种异常类型,回滚事务。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 JyBlog🏀🐓!