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;
}
}
重用切入点
切面优先级