java - 是否存在更好的方式来记录更新历史记录?

标签 java logging aspectj audit-logging

在我们的后端系统中,有很多情况需要更新对象,例如更新商品、更新商品价格、更新用户、更新状态、更新订单(取消、更新价格)等。现在有些对象我们有一个特殊的日志表,例如order_update_log ,记录更新操作。有些仅记录到文件,例如

logger.info("goods update: before: {}, after: {}", oldGoods, newGoods)

感觉处理这些琐碎的事情很烦人,是否存在一些更好的方式/工具来处理这样的记录器?

最佳答案

有一个非常好的东西叫做方面。 您可以为您的项目编写仅了解跟踪商品对象更改的方面。假设你有Goods类:

public class Goods {
    private Integer id;
    private String name;
    private BigDecimal cost;

    // Getters, Setters
    ...
}

映射到数据库表goods并具有相应字段:

CREATE TABLE `goods` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` varchar NOT NULL,
    `cost` DECIMAL NOT NULL,
    PRIMARY KEY (`id`)
);

假设你有GoodsService :

public class GoodsService {

    public Goods read(Integer id) {
        Goods goods = /* Read goods from database */
        return goods;
    }

    public void write(Goods goods) {
        /* Write goods to database */
    }
}

GoodsController使用GoodsService :

public class GoodsController {

    private GoodsService goodsService;

    public void updateGoods(Integer id, String name, BigDecimal cost) {
        Goods goods = goodsService.read(id);
        goods.setName(name);
        goods.setCost(cost);
        goodsService.write(goods);
    }

}

因此,让我们为您的项目添加一些神奇的方面,以跟踪 cargo 的变化。现在创建另一个表,其中包含用于存储 user 的附加字段。和datetime更新goods对象:

CREATE TABLE `goods_log` (
    `revision` INT NOT NULL AUTO_INCREMENT,
    `id` INT NOT NULL,
    `name` varchar NOT NULL,
    `cost` DECIMAL NOT NULL,
    `user` varchar NOT NULL,
    `timestamp` DATETIME NOT NULL,
    PRIMARY KEY (`revision`,`id`)
);

编写方面类:

@Aspect
public class GoodsLogger {
    @Before(value = "execution(* org.antonu.service.GoodsService.write(..)) && args(goods)")
    public void logWrite(Goods goods) {
        // Get current user and timestamp,
        // Write it to goods_log table, as well as goods data
    }
}

就是这样!你的业务逻辑代码没有改变,读起来很清楚。但是每次调用 GoodsService 的 write 方法时,您都会在 Goods_log 中获得包含新商品状态的记录。

要使此代码正常工作,应使用 AJC 编译器进行编译,还应包含aspectjrt 库。通过maven可以轻松完成:

<properties>
    <aspectj.version>1.8.7</aspectj.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

现代 IDE Intellij Idea 应自动使用 AJC编译器与上面的maven配置。如果没有,您必须通过 File - Settings - 'Build, Execution, Deployment' - Compiler - Java Compiler - Use compiler: Ajc. 配置编译器AJC编译器路径:<path_to>/aspectjtools-1.8.7.jar

关于java - 是否存在更好的方式来记录更新历史记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33803359/

相关文章:

java - Log4j2 配置中的 “status” 是什么意思?

eclipse - 无法在 Eclipse 中为 AspectJ 项目创建运行/调试配置

java - 为什么 Spring @Value 与 @Controller 不兼容?

java - PointCut 将使用某些参数注释的方法与注释相匹配

Java Attach API : changing java. library.path 动态

c - Linux 中的守护进程日志记录

C# Application Insights - TelemetryClient 的多个实例

java - 交易异常 : Transaction not successfully started

java - Hibernate错误org.hibernate.exception.SQLGrammarException : Table . ..不存在

java - Groovy 闭包可以扩展抽象类吗