AOP面向切面编程和log4j的使用(Java版)

  • 什么是面向切面编程

        在传统的面向对象编程中,程序的功能被模块化成各个类和方法,这些类和方法分别处理特定的功能。然而,有些功能可能涉及到多个类、多个方法,例如日志记录、事务管理、性能监控等,这些功能可能在不同的地方重复出现,导致代码的重复性和复杂性增加。

AOP 解决了这个问题,它允许你在程序的运行时,将这些横切逻辑(cross-cutting concerns)从它们所影响的对象中分离出来,然后以一种更模块化的方式进行管理。

  • 示例

        客户端请求服务端接口时,记录请求的接口信息,包括接口请求时间、接口名称、请求内容以及返回结果等信息。实现步骤如下:

        1. 配置log4j的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>

    <Appenders>
        <!--控制台输出的配置-->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <!--输出到文件的配置-->
        <RollingFile name="RollingFile" fileName="./data/logs/app.log"
                     filePattern="./data/logs/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>

</Configuration>

        2. 在项目中添加依赖(log4j和AOP)

<!-- 引入log4j2依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<!--AOP-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        3. 创建一个拦截器类,用于拦截Api请求和响应,记录日志。

@Slf4j
@Aspect   //定义一个切面
@Component  //标记该类作为Spring托管的组件。可以通过依赖注入在其他地方使用
public class ApiMonitorFilter{
    //在执行com.example.service包下所有的方法之后打印日志
    @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
    public void logAPICall(JoinPoint joinPoint, Object result) {
        long currentTime = System.currentTimeMillis();
        String apiName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();

        ObjectMapper objectMapper = new ObjectMapper();
        String aa=null;
        try {
            aa=objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        log.info("进入过滤器:开始监控api信息.........");
        log.info("接口相应时间{}:",currentTime);
        log.info("接口名称{}:",apiName);
        log.info("请求内容{}:",aa);
        log.info("响应结果{}:",result);
    }
}

        2. 写一个接口

//@Controller  //@Controller返回的是一个视图View,需要搭配@ResponseBody使用,两个的结合相当于@RestController,可以直接返回一个对象。
//@ResponseBody
@RestController
@RequestMapping("/api/test")
@Slf4j
public class TestController {
    @Resource
    TestService testService; //接口中调用的方法  import com.example.service.TestService;

    @PostMapping(value = "/getValue")
    public  String GetValue(int a,int b){
        log.info("进入Controller");
        String result=testService.CalculateValue(a,b);
        return  result;
    }
}

运行结果:

### Java AOP面向切面编程)概念 Java AOP 是一种编程范式,旨在通过分离横切关注点来提高模块化程度。横切关注点是指那些影响多个类的功能,如事务管理、日志记录安全性等。这些功能通常散布于整个应用的不同部分,难以维护修改。 Spring AOP 提供了声明式编程式的 AOP 实现,其中较常用的是声明式 AOP[^1]。这种技术允许开发者定义特定的行为——称为“方面”,并将其应用于程序的其他部分而不改变原有业务逻辑代码。 ### 创建增强方法所在类 (切面) 为了实现增强功能,需要创建一个包含增强逻辑的方法所在的类: ```java package Semester_4.AOP.JDKDynamicProxy.intensifier; public class MyAspect { public void checkPermissions(){ System.out.println("模拟检查权限的过程……"); } public void log(){ System.out.println("模拟记录权限的过程……"); } } ``` 上述代码展示了如何在一个名为 `MyAspect` 的类中定义两个简单的增强函数:一个是用于模拟权限验证过程,另一个则是用来打印日志信息[^2]。 ### 日志记录功能的应用场景 在实际开发过程中,利用 Spring AOP 可以方便地实现在不侵入原业务逻辑的情况下添加额外行为的需求。比如,在应用程序内部自动捕获所有公共接口调用的信息,并将它们写入到文件或其他存储介质里去。这不仅简化了编码工作量还提高了系统的可读性灵活性[^3]。 ### 定义切面类与配置切入点表达式 下面是一个具体的例子展示怎样基于 AspectJ 注解风格来构建一个完整的切面组件: ```java @Aspect @Component public class LogAspect { /** * Before注解: 前置通知,在目标方法执行之前执行; * value参数: 切入点表达式,指定哪些方法需要被植入增强逻辑; */ @Before(value = "execution(public int cn.tedu._07springaop.aop.CalculatorImpl.*(..))") public void beforeMethod() { //前置通知的增强逻辑 System.out.println("即将执行计算操作..."); } /* 还可以有其他的环绕通知(@Around), 后置返回通知 (@AfterReturning), 抛出异常后的处理(@AfterThrowing),以及最终的通知(@After) */ } ``` 这段代码片段说明了一个典型的切面类结构及其基本组成部分。这里使用了 `@Aspect` `@Component` 来标记该类为一个切面组件;并通过 `@Before` 注解读取切入点表达式从而决定何时触发相应的增强逻辑[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值