Spring切面編程實踐【原創】
阿新 • • 發佈:2019-03-11
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; privateLocalTime 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 extendsBaseEntity { 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切面編程實踐【原創】