Spring切面编程实践【原创】

定义

什么叫Spring面向切面编程(AOP),请自行百度,这边就不做详细介绍了。

场景

有两个对象,字典和工程信息Bean,每次新增或修改对象时,记录新增和修改的时间。

基类定义

package myTest.entity;

import lombok.Data;

import java.time.LocalTime;

/**
 * entity基类
 */
@Data
public class BaseEntity {
    private Long id;
    private LocalTime createTime;
    private LocalTime updateTime;
}

子类定义

package myTest.entity;

import lombok.Data;

/**
 * 字典信息
 */
@Data
public class DictEntity extends BaseEntity{
    private String key;
    private String value;
}
package myTest.entity;

import lombok.Data;

/**
 * 项目信息
 */
@Data
public class ProjectEntity extends BaseEntity {
    private String projectName;
}

注:这边使用了lombok,不熟悉的同学可以查看https://www.cnblogs.com/meituan/p/10510889.html

常规做法

service基类

package myTest.service;


public interface BaseService<T> {
    void save(T entity);
    void update(T entity);
}

字典Service实现

package myTest.service;

import myTest.entity.DictEntity;import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalTime;

public class DictService implements BaseService<DictEntity> {

    @Autowired
    private DictDao dao;

    @Override
    public void save(DictEntity entity){
        entity.setCreateTime(LocalTime.now());
        entity.setUpdateTime(LocalTime.now());
        dao.save(entity);
    }

    @Override
    public void update(DictEntity entity){
        entity.setUpdateTime(LocalTime.now());
        dao.update(entity);
    }
}

工程Service实现

 

package myTest.service;

import myTest.entity.ProjectEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalTime;

@Service
public class ProjectService implements BaseService<ProjectEntity> {

    @Autowired
    private ProjectDao dao;

    @Override
    public void save(ProjectEntity entity){
        entity.setCreateTime(LocalTime.now());
        entity.setUpdateTime(LocalTime.now());
        dao.save(entity);
    }

    @Override
    public void update(ProjectEntity entity){
        entity.setUpdateTime(LocalTime.now());
        dao.update(entity);
    }

}

反思

常规做法做了重复劳动工作,如果entity子类更多的话,重复劳动会更多,而且很不容易维护,这时候就可以用到Spring的切面编程思想。

使用Spring AOP解决问题

大致思路可以这样,当Service执行save和update方法的时候,定义一个切点,在执行到这个切点的时候,统一加入更新时间和新增时间的控制,一处增加,多处使用,省时省力,而且便于维护。上代码!

  • 首先,在pom文件中引入aspect依赖的jar包,如下

   

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>
  • 其次,定义切点和前置通知

  

package myTest;

import myTest.entity.BaseEntity;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;

/**
 * 定义切点和前置通知,统一修改新增时间和修改时间
 */
@Aspect
@Component
public class Asepect {

    @Pointcut("execution(* myTest.service.DictService.save*(..)) || execution(* myTest.service.DictService.update*(..)) || " +
            "execution(* myTest.service.ProjectService.save*(..)) || execution(* myTest.service.ProjectService.update*(..))")
    public void addAndUpdatePointCut(){}

    @Before("addAndUpdatePointCut()")
    public void before(JoinPoint joinPoint) {
        //获取方法名
        String mathName = joinPoint.getSignature().getName();
        //获取参数列表
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        for (Object o :
                args) {
            if (o instanceof BaseEntity) {
                ((BaseEntity) o).setUpdateTime(LocalTime.now());
                if (mathName.startsWith("save")) {
                    ((BaseEntity) o).setCreateTime(LocalTime.now());
                }
            }
        }
    }

}

就这样两个简单的步骤,就可以解决原始方法带来的重复工作和不易维护的问题,是不是很爽?

【纯手打,请多多支持,谢谢】

 

猜你喜欢

转载自www.cnblogs.com/meituan/p/10511843.html