一.@annotation注解
我们在最后一个切入点表达式中要匹配多个无规则的方法,这样的写法有些冗余了。而@annotation注解就是来解决这一问题的。
@annotation注解使用特定的注解来匹配方法。我们首先自定义一个注解,该注解就相当于一个标签,目标对象上面加上了这个标签,我们在切入点表达式中的@annotation中引入这个标签,标签下面的目标对象就会在执行时执行切入点表达式下面的通知方法。
我们首先自定义一个注解,注解的名字就叫MyLog
其中@Retention()指定该注解什么时候生效,RetentionPolicy.RUNTIME表示运行时生效。
@Target()指定生效的地方,ElementType.METHOD表示注解生效在方法上
package com.gjw.aop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 指定该注解什么时候生效
@Target(ElementType.METHOD) // 指定生效的地方,注解生效在方法上
public @interface MyLog {
}
定义好后,我们在需要引入通知的地方加上该注解,如在com.gjw.service.DeptService.deleteById和com.gjw.service.DeptService.list()上加上
package com.gjw.service.impl;
import com.gjw.aop.MyLog;
import com.gjw.mapper.DeptMapper;
import com.gjw.pojo.Dept;
import com.gjw.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
// @Autowired
// private EmpMapper empMapper;
//
// @Autowired
// private DeptLogService deptLogService;
@MyLog
@Override
public List<Dept> list() {
return deptMapper.list();
}
// @Transactional(rollbackFor = Exception.class) // spring事务管理 方法开始执行之前开启事务,方法执行完毕之后提交事务,方法运行过程中出现异常会回滚事务 rollbackFor:定义异常出现后回滚的类型,Exception.class表示不论出现任何异常均回滚事务,而默认只出现运行时异常才回滚事务
@Transactional
@Override
@MyLog
public void deleteById(Integer id) {
// 根据部门id删除部门,同时也要删除部门下的员工
try {
deptMapper.deleteById(id);
// int a = 1/0;
//
// empMapper.deleteByDeptId(id);
} finally {
// DeptLog deptLog = new DeptLog();
// deptLog.setCreateTime(LocalDateTime.now());
// deptLog.setDescription("删除id为"+id+"的部门");
// deptLogService.insert(deptLog);
}
}
@Override
public void add(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
deptMapper.insert(dept);
}
@Override
public Dept getById(Integer id) {
// int i = 1/0;
return deptMapper.getById(id);
}
@Override
public void update(Dept dept) {
dept.setUpdateTime(LocalDateTime.now());
deptMapper.update(dept);
}
}
然后我们在通知方法上面使用@annotation注解进行定义
package com.gjw.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
//@Aspect
@Slf4j
public class MyAspect7 {
@Before("@annotation(com.gjw.aop.MyLog)") // 指定定义注解的全类名,此时就代表上面加上@MyLog注解的方法在运行时会调用该通知方法
public void before() {
log.info("MyAspect7......before......");
}
}
在@annotation注解中进入MyLog的全类名即可。这样就会在引用@MyLog注解的方法执行时自动执行通知方法了。