2022-9-21 Spring学习笔记
1.Spring
1.1 bean的生命周期
- 构造器
- 属性注入
- 初始化方法
- 目标方法
- 销毁方法
延迟初始化(懒初始化)
- servlet的初始化。默认是延迟初始化。只要不启动,就不会初始化。
- spring的IOC容器默认就是非延迟初始化。只要spring的容器启动,所有的bean都会加载,都会初始化。
1.2 AOP
面向切面编程,主要用来解决系统层面上的问题,例如:日志,事务,权限
- 在不改变原有的逻辑的基础上,增加一些儿额外的功能
- AOP是OOP(面向对象)的补充和完善
- AOP横切技术,剖解开对象的内部,把一些和业务无关的,却可以为业务共同的调用的逻辑封装起来,减少重复代码的使用。
通知
增强处理(Advice)
- 先定义好日志,事务或权限,然后再想用的地方,Advice配合Aspect的一段处理代码。
连接点
JoinPoint
就是Spring允许你通知的地方。
- 例如:一个service层的方法需要配置通知,获取这个方法的参数,方法名,返回值...
切入点
PointCut
一个类中有多个方法,让这些方法中的某几个方法再执行之前,执行之后或抛出异常时做些什么,使用切入点表达式来筛选连接点。
切面
通知和切入点的结合,在什么点上去干什么事
织入
被通知的对象,真正的业务逻辑,可以毫不知情。两者或许之间可能并不知情,专注于自己该做的事。
1.3 配置AOP
使用xml文件配置
<!-- AOP-->
<aop:config>
<!-- 面向切面-->
<aop:aspect ref="myAop">
<!-- 切点表达式-->
<aop:pointcut id="logAspectPointCut" expression="execution(* com.jsoft.service.impl.*.*(..))"/>
<!-- 在expression表达式指定的方法执行之前去执行myAop里的before方法
pointcut-ref:在什么切点之前-->
<aop:before method="before" pointcut-ref="logAspectPointCut"></aop:before>
<!-- 在expression表达式指定的方法执行之后去执行myAop里的after方法
pointcut-ref:在什么切点之后-->
<aop:after method="after" pointcut-ref="logAspectPointCut"></aop:after>
<!-- 出现异常执行-->
<aop:after-throwing method="throwing" pointcut-ref="logAspectPointCut"></aop:after-throwing>
<!-- 成功返回执行-->
<aop:after-returning method="returning" pointcut-ref="logAspectPointCut"></aop:after-returning>
</aop:aspect>
</aop:config>
使用注解配置
开启自动扫描
<!-- 开启aop的注解扫描-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyLog {
}
// 带Mylog注解才会执行对应的方法
@MyLog
public Account findAccountById(Integer id) {
System.out.println("findAccountById方法执行中...");
// int i = 10 / 0;
return accountDao.findAccountById(id);
}
注解
@Before("execution(* com.jsoft.service.impl..(..))")
- 根据表达式
- 只有满足表达式里的条件的才会执行对应的方法
@Before("@annotation(com.jsoft.annotation.MyLog)")
- 根据自定义注解
- 只有在需要用的地方加上自定义的注解,才会执行对应的方法
// 切面注解
@Aspect
public class MyAOP {
// @Before("execution(* com.jsoft.service.impl.*.*(..))") 表达式
// @Before("@annotation(com.jsoft.annotation.MyLog)") 根据自定义注释
public void before(JoinPoint joinPoint) {
System.out.println("执行方法之前打印一条日志!");
// 获取目标方法的参数们
Object[] args = joinPoint.getArgs();
// 调用目标方法的那个对象
Object aThis = joinPoint.getThis();
// 代理对象
Object target = joinPoint.getTarget();
}
// @After("execution(* com.jsoft.service.impl.*.*(..))")
public void after() {
System.out.println("执行方法之后打印一条日志!");
}
// @AfterThrowing(value = "execution(* com.jsoft.service.impl.*.*(..))",throwing = "e")
public void throwing(JoinPoint joinPoint,Throwable e) {
System.out.println("出现了异常...");
// 获取到异常信息
System.out.println(e.getMessage());
// 获取到异常类型
System.out.println(e.getClass());
}
// @AfterReturning(value = "execution(* com.jsoft.service.impl.*.*(..))",returning = "result")
public void returning(JoinPoint joinPoint,Object result) {
System.out.println("正常的返回结果...");
// 方法的返回值
System.out.println(result);
}
// @Around("execution(* com.jsoft.service.impl.*.*(..))")
public void around(ProceedingJoinPoint joinPoint) {
System.out.println("before...");
try {
// 执行目标方法
Object o = joinPoint.proceed();
System.out.println(o);
System.out.println("returning...");
}catch (Throwable e){
System.out.println("throwing...");
}
System.out.println("after...");
}
开启自动扫描后,才能使用注解
1.4 切面表达式
execution(* com.jsoft.service.impl..(..))
- execution:声明接下来的是一个表达式
- *:访问权限
- com.jsoft.service.impl:包
- *:类
- *:方法名
- (..):参数类型

浙公网安备 33010602011771号