1. 程式人生 > >Spring切面編程實踐【原創】

Spring切面編程實踐【原創】

color 維護 alt name 步驟 creat point ice npoi

定義

什麽叫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());
                }
            }
        }
    }

}

就這樣兩個簡單的步驟,就可以解決原始方法帶來的重復工作和不易維護的問題,是不是很爽?

【純手打,請多多支持,謝謝】

 

Spring切面編程實踐【原創】