用aop实现登陆日志、和操作日志持久化
在 Java 中,可以使用 **AOP(Aspect-Oriented Programming)**来实现登录日志和操作日志的持久化功能。通过 AOP,我们可以将日志记录这类 **横切关注点(cross-cutting concerns)**从业务逻辑中分离出来,实现更好的代码结构和可维护性。下面是一个简单的示例代码,演示如何使用 AOP 在登录和操作时记录日志并将日志持久化到数据库中。
假设我们有一个 UserService
类处理用户登录相关的操作,我们希望在用户登录成功或者进行操作时记录日志并将日志持久化到数据库中。
-
定义日志实体类:
public class Log { private String username; private String action; private Date timestamp; // 省略构造函数和getter/setter方法 }
-
定义日志记录切面:
@Aspect @Component public class LogAspect { private final Logger logger = LoggerFactory.getLogger(LogAspect.class); @Autowired private LogRepository logRepository; @Around("execution(* com.example.UserService.login(..))") public Object logLogin(ProceedingJoinPoint joinPoint) throws Throwable { Object result = joinPoint.proceed(); Log log = new Log(); log.setUsername((String) joinPoint.getArgs()[0]); log.setAction("User login"); log.setTimestamp(new Date()); logRepository.save(log); return result; } @Around("execution(* com.example.UserService.*(..)) && !execution(* com.example.UserService.login(..))") public Object logOperation(ProceedingJoinPoint joinPoint) throws Throwable { Object result = joinPoint.proceed(); Log log = new Log(); log.setUsername("admin"); // 可以根据实际情况获取当前操作用户 log.setAction("User operation: " + joinPoint.getSignature().getName()); log.setTimestamp(new Date()); logRepository.save(log); return result; } }
-
定义日志持久化 Repository:
@Repository public interface LogRepository extends JpaRepository<Log, Long> { // 可以自定义需要的持久化操作 }
-
在配置类中启用 AOP:
@Repository public interface LogRepository extends JpaRepository<Log, Long> { // 可以自定义需要的持久化操作 }
在以上示例中,我们定义了一个
LogAspect
切面类,通过@Around
注解拦截了UserService
类中的login
方法和其他操作方法,并在切面中记录日志,并通过LogRepository
将日志持久化到数据库中。通过 AOP 的方式,我们实现了登录日志和操作日志的持久化功能,使得这部分代码与业务逻辑相分离,提高了代码的可维护性和扩展性。 -
AOP常用注解
在 Spring 框架中,用于支持 AOP(Aspect-Oriented Programming)的主要注解包括:
- @Aspect:用于定义一个切面(Aspect),标识一个类为切面,在其中定义通知和切点。
- @Before:前置通知,在目标方法执行前执行。
- @After:后置通知,在目标方法执行后执行。
- @Around:环绕通知,在目标方法执行前后都可以执行自定义的行为。
- @AfterReturning:返回通知,在目标方法成功执行后执行。
- @AfterThrowing:异常通知,在目标方法抛出异常时执行。
- @Pointcut:定义切点,可以重复使用的切点表达式。
- @DeclareParents:引入增强,允许向现有的类添加新的方法和属性。