🥝FANMR.CN热爱,追求
Spring介绍

Spring介绍

Spring是一款主流的Java EE轻量级开源框架,目的是用于简化Java企业级应用的开发难度和开发周期

Spring划分

  • 广义上:值以Spring Framework为核心的Spring技术栈,由很多子项目组成,如:SpringBoot、Spring MVC、Spring Cloud、Spring Data等
  • 狭义上:专指Spring Framework,两大核心:IOC和AOP

注意:Spring6需要JDK17

AOP示例

对日志进行切面编程

AOP相关术语

  • 横切关注点:具有相同代码的地方
  • 通知(增强):具体要增强的功能
  • 切面:封装通知方法的类
  • 目标:被代理的目标对象
  • 代理:想目标对象应用通知之后创建的代理对象
  • 连接点:允许使用通知的地方
  • 切入点:实际要增强的方法

Spring通知类型

  • 前置通知:在连接点之前执行的通知(@Before)
  • 后置通知:当连接点退出的时候执行的通知(@After)
  • 返回通知:在连接点正常完成后执行的通知(@AfterReturning)
  • 异常通知:在方法抛出异常退出时执行的通知(@AfterThrowing)
  • 环绕通知:包围一个连接点的通知,包含上面4个(@Around)

AOP实现方式

使用的是动态代理:有接口使用JDK动态代理,没有接口使用CGLIB动态代理

AOP使用实例

图

@Aspect
@Component
public class LoggingAspect {
 
    @Before("execution(* com.myapp.service.*.*(..))")
    public void beforeServiceMethodExecution() {
        System.out.println("Before method execution...");
    }
 
    @AfterReturning("execution(* com.myapp.service.*.*(..))")
    public void afterServiceMethodExecution() {
        System.out.println("After method execution...");
    }
 
    @AfterThrowing(pointcut = "execution(* com.myapp.service.*.*(..))", throwing = "ex")
    public void afterServiceMethodException(Throwable ex) {
        System.out.println("After method throws exception... " + ex.getMessage());
    }
 
    @Around("execution(* com.myapp.service.*.*(..))")
    public Object aroundServiceMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before method execution...");
        try {
            Object result = joinPoint.proceed();
            System.out.println("After method execution...");
            return result;
        } catch (Throwable e) {
            System.out.println("Exception thrown: " + e.getMessage());
            throw e;
        }
    }
}

获取通知的方法信息

图

获取方法返回值示例

@Aspect
@Component
public class LoggingAspect {
    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @AfterReturning(value = "execution(* com.example.service.UserService.getUserById(..))", returning = "user")
    public void logUser(User user) {
        logger.info("User {} has been retrieved.", user.getName());
    }
}

获取异常示例

@Aspect
@Component
public class LoggingAspect {
    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @AfterThrowing(value = "execution(* com.example.service.UserService.deleteUserById(..))", throwing = "exception")
    public void logDeleteUserException(UserNotFoundException exception) {
        logger.error("Failed to delete user. Error message: {}", exception.getMessage());
    }
}

环绕通知示例

@Aspect
@Component
public class LoggingAspect {
    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Around("execution(* com.example.service.UserService.updateUser(..))")
    public Object logUpdateUser(ProceedingJoinPoint joinPoint) {
        // 目标方法名
        joinPoint.getSignature().getName()
        // 目标参数
        joinPoint.getArgs()
        // 返回值
        Object result = null;
        try {
            // 调用目标方法
            result = joinPoint.proceed();
        } catch (Throwable e) {
            System.out.println("出现异常(与异常通知作用相似)")
        } finally {
            System.out.println("最后执行(与后置通知作用相似)")
        }

        long endTime = System.currentTimeMillis();
        logger.info("Finish updating user. Execution time: {} ms.", endTime - startTime);

        return result;
    }
}

重用切入点

图

图

切面优先级

图