通过自定义注解与aop统一存储操作记录
Posted zhlblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过自定义注解与aop统一存储操作记录相关的知识,希望对你有一定的参考价值。
模块开发完成后,接到通知需要添加操作记录功能,看着那一堆接口,如果一个方法一个方法的加,那真是太麻烦了。为了偷懒,就百度了一下,发现可以通过自定义注解和aop的形式来统一添加操作记录,只需要在每个方法上面添加自定义的注解就可以了。我在这里用的是springboot2.0以及jpa,废话不多说,直接上代码~
自定义注解serverLog
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 请输入一段话进行描述 * * @author Holley * @create 2018-07-03 14:23 **/ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface serverLog { public String comment() default ""; }
aop
import com.springcloud.serviceclient01.dao.OperationDao; import com.springcloud.serviceclient01.model.Operation; import com.springcloud.serviceclient01.model.User; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.Date; /** * 请输入一段话进行描述 * * @author Holley * @create 2018-07-03 16:57 **/ @Aspect @Order(2) @Component public class TestAop { @Autowired private OperationDao operationDao; /** * @Author holley * @Description 第一种设置切点的方式 * 定义切点(添加severLog的方法),log是参数(该切点的serverLog注解的实例变量) * @Date 2018/7/3 17:09 * @Param * @return */ @Pointcut("@annotation(log)") public void severLog(serverLog log){ } /** * @Author holley * @Description JoinPoint joinPoint参数在所有类型通知中都可直接调用,表示和切面的连接点,可以通过词参数获取切面方法的参数等 * @Date 2018/7/3 17:55 * @Param * @return */ @After("severLog(log)") public void rightback(JoinPoint joinPoint, serverLog log){ // 可以在此处通过 获取token得到当前登陆人的信息,也可以通过缓存获取,然后存入操作记录 Operation operation = new Operation(); operation.setContent(log.comment()); operation.setCreated(new Date()); operationDao.save(operation); System.out.println("切面的所有参数:" + Arrays.toString(joinPoint.getArgs())); } /** * @Author holley * @Description returning 定义该切面(添加了severLog注解的方法)的返回结果 * @Date 2018/7/3 17:41 * @Param * @return */ @AfterReturning(returning = "u", pointcut = "severLog(log)") public void endback(JoinPoint joinPoint,User u,serverLog log){ System.out.println(u.toString()+"-----------------------"+log.comment()); System.out.println("切面的所有参数:" + Arrays.toString(joinPoint.getArgs())); } /** * @Author holley * @Description 第二种设置切点的方式 * 第一个星号:表示返回类型,*号表示所有类型 * 第二个星号:表示设置为切点的类名,*号表示所有的类 * 第三个星号:表示设置为切点的类的方法名,*号表示该类中所有的方法 * 括弧里表示方法的参数,两个点表示任何参数 * @Date 2018/7/3 17:48 * @Param * @return */ @Pointcut("execution(* com.springcloud.serviceclient01.service.impl..*.*(..))") public void severTest(){ } }
controller层
import com.springcloud.serviceclient01.model.User; import com.springcloud.serviceclient01.service.Helloservice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * 请输入一段话进行描述 * * @author Holley * @create 2018-07-03 15:12 **/ @RestController @RequestMapping("/hello") public class HelloController { @Autowired private Helloservice helloservice; @GetMapping("/{sid}") public String Hello(@PathVariable("sid") Long sid){ User u = helloservice.getUserByid(sid); return u.toString(); } @GetMapping("/test/{sid}") public String test1(@PathVariable("sid") Long sid){ String name = helloservice.findByUid(sid); return name; } /** * @Author holley * @Description 注意:使用spring注解将变量直接用/加在地址栏后时,不能传字符串,如:localhost:18762/hello/name/2/川普 * 正确如下 * localhost:18762/hello/name/2?name=川普 * @Date 2018/7/3 16:19 * @Param * @return */ @GetMapping("/name/{sid}") public String test2(@PathVariable("sid") Long sid,@RequestParam("name")String name){ String p = helloservice.findByUser(sid,name); return p; } /** * @Author holley * @Description 证明不能传字符串格式的参数 * @Date 2018/7/3 16:23 * @Param * @return */ /*@GetMapping("/a/{name}") public String test3(@PathVariable("name")String name){ System.out.print(name + "测试成功--------------"); return name; }*/ }
serviceimpl层
import com.springcloud.serviceclient01.aop.serverLog; import com.springcloud.serviceclient01.dao.UserDao; import com.springcloud.serviceclient01.model.User; import com.springcloud.serviceclient01.service.Helloservice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 请输入一段话进行描述 * * @author Holley * @create 2018-07-03 14:33 **/ @Service("helloservice") public class HelloServiceImpl implements Helloservice{ @Autowired private UserDao userDao; @serverLog(comment = "根据id查询用户") @Override public User getUserByid(Long id) { return userDao.getOne(id); } @Override public String findByUid(Long id) { return userDao.findByaa(id); } @Override public String findByUser(Long id, String name) { return userDao.findUser(id,name); } }
dao层
import com.springcloud.serviceclient01.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.transaction.annotation.Transactional; /** * 继承JpaRepository,第二个泛型参数为User类主键的类型 * * @author Holley * @create 2018-07-03 14:38 **/ public interface UserDao extends JpaRepository<User,Long> { /** * @Author holley * @Description 注意:使用jpa时,User不是数据库中的表名,而是实体类的类名 * @Date 2018/7/3 16:12 * @Param * @return */ @Transactional(timeout = 10) @Query("select name from User where uid = ?1") String findByaa(Long uid); @Transactional(timeout = 10) @Query("select password from User where uid = ?1 and name = ?2") String findUser(Long uid,String name); }
import com.springcloud.serviceclient01.model.Operation; import org.springframework.data.jpa.repository.JpaRepository; /** * 继承JpaRepository,第二个泛型参数为User类主键的类型 * * @author Holley * @create 2018-07-03 14:38 **/ public interface OperationDao extends JpaRepository<Operation,Long> { }
model
import javax.persistence.*; /** * 请输入一段话进行描述 * * @author Holley * @create 2018-07-03 14:34 **/ @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long uid; private String name; private String password; @Column(name ="is_opt_required") private Integer isOptRequired; public Long getUid() { return uid; } public void setUid(Long uid) { this.uid = uid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getIsOptRequired() { return isOptRequired; } public void setIsOptRequired(Integer isOptRequired) { this.isOptRequired = isOptRequired; } @Override public String toString() { return "User{" + "uid=" + uid + ", name=‘" + name + ‘‘‘ + ", password=‘" + password + ‘‘‘ + ", isOptRequired=" + isOptRequired + ‘}‘; } }
import javax.persistence.*; import java.util.Date; /** * 操作表的实体类 * * @author Holley * @create 2018-06-05 14:12 **/ @Entity public class Operation { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long opid; private Long sid; private Long oid; private Long pid; private Long uid; private String account; private String content; private Date created; @Transient private String orderCode; @Transient private String pname; @Transient private String sname; public Long getOpid() { return opid; } public void setOpid(Long opid) { this.opid = opid; } public Long getOid() { return oid; } public void setOid(Long oid) { this.oid = oid; } public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public Long getUid() { return uid; } public void setUid(Long uid) { this.uid = uid; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } public Long getSid() { return sid; } public void setSid(Long sid) { this.sid = sid; } public String getOrderCode() { return orderCode; } public void setOrderCode(String orderCode) { this.orderCode = orderCode; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } @Override public String toString() { return "Operation{" + "opid=" + opid + ", sid=" + sid + ", oid=" + oid + ", pid=" + pid + ", uid=" + uid + ", account=‘" + account + ‘‘‘ + ", content=‘" + content + ‘‘‘ + ", created=" + created + ", orderCode=‘" + orderCode + ‘‘‘ + ", pname=‘" + pname + ‘‘‘ + ", sname=‘" + sname + ‘‘‘ + ‘}‘; } }
参考文档:
https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html
https://www.zifangsky.cn/788.html
https://blog.csdn.net/qq_34021712/article/details/78680915
经过测试,完全可以跑通,如果有什么问题,欢迎各位大神来拍砖~
以上是关于通过自定义注解与aop统一存储操作记录的主要内容,如果未能解决你的问题,请参考以下文章