1.导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.创建项目工程
1.启动类
@SpringBootApplication
public class OpenApplication {
public static void main(String[] args) {
SpringApplication.run(OpenApplication.class, args);
}
}
2.实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TSyslog implements Serializable {
private static final long serialVersionUID = -49462392451873347L;
private Integer id;
/**
* 操作人
*/
private String operationName;
/**
* 操作内容
*/
private String content;
/**
* 操作IP
*/
private String ip;
/**
* 操作人id
*/
private Integer userId;
/**
* 请求参数
*/
private String operRequParam;
/**
* 请求方法
*/
private String operRequMethod;
/**
* 创建时间
*/
private String createTime;
3.mapper层
@Mapper
public interface TSyslogDao {
/**
* 新增数据
*
* @param tSyslog 实例对象
* @return 影响行数
*/
int insert(TSyslog tSyslog);
}
4.mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ld.open.dao.TSyslogDao">
<resultMap type="com.ld.open.entity.TSyslog" id="TSyslogMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="operationName" column="operation_name" jdbcType="VARCHAR"/>
<result property="content" column="content" jdbcType="VARCHAR"/>
<result property="ip" column="ip" jdbcType="VARCHAR"/>
<result property="userId" column="user_id" jdbcType="INTEGER"/>
<result property="operRequParam" column="oper_requ_param" jdbcType="VARCHAR"/>
<result property="operRequMethod" column="oper_requ_method" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into uzi.t_syslog(operation_name, content, ip, user_id, oper_requ_param, oper_requ_method, create_time)
values (#{operationName}, #{content}, #{ip}, #{userId}, #{operRequParam}, #{operRequMethod}, #{createTime})
</insert>
</mapper>
5.service层和impl层
public interface TSyslogService {
/**
* 新增数据
*
* @param tSyslog 实例对象
* @return 实例对象
*/
TSyslog insert(TSyslog tSyslog);
}
@Service("tSyslogService")
public class TSyslogServiceImpl implements TSyslogService {
@Resource
private TSyslogDao tSyslogDao;
/**
* 新增数据
*
* @param tSyslog 实例对象
* @return 实例对象
*/
@Override
public TSyslog insert(TSyslog tSyslog) {
this.tSyslogDao.insert(tSyslog);
return tSyslog;
}
}
6.controller测试层
@RestController
@RequestMapping
public class TAdminController {
/**
* 服务对象
*/
@Resource
private TAdminService adminService;
@RequestMapping(value = "/login")
public String login(){
return "hello!";
}
}
7.(重点)aspect切面
@Component("SysLogAspect")
@Aspect
public class SysLogAspect {
@Autowired
private TSyslogService syslogService;
//前置通知
@Before("execution(public * com.xxx.open.controller.TAdminController.login(..))")
public void before(JoinPoint jp) {
System.out.println("前置通知:获得目标类名:"+jp.getTarget().getClass().getName());
System.out.println("前置通知:获得目标方法签名:"+jp.getSignature());
}
//后置通知
@AfterReturning(value = "execution(public * com.xxx.open.controller.TAdminController.login(..))",returning = "res")
public void afterReturning(JoinPoint jp,Object res) {
System.out.println("后置通知,目标方法的返回值为:"+res);
Signature signature = jp.getSignature();
String s = signature.toLongString();
TSyslog syslog = new TSyslog();
syslog.setUserId(1);
syslog.setOperationName("Admin");
syslog.setCreateTime(TimeUtil.currentTime());
syslog.setContent("登录的方法");
syslog.setIp("127.0.0.1");
syslog.setOperRequMethod(s);
syslog.setOperRequParam((String) res);
syslogService.insert(syslog);
}
//环绕通知:ProceedingJoinPoint中的proceed()的执行就是执行目标方法
@Around("execution(public * com.xxx.open.controller.TAdminController.login(..))")
public Object around(ProceedingJoinPoint pjp) {
Object res=null;
try {
System.out.println("环绕通知的前置增强");
res = pjp.proceed();
System.out.println("环绕通知的后置增强");
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;
}
//异常通知:异常 通知可以包含一个Throwable类型的参数,其参数名e和配置中的throwing指定名相同,表示当前发生的异常对象
@AfterThrowing(value = "execution(public * com.xxx.open.controller.TAdminController.login(..))",throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("异常通知,异常类型为:"+e.getClass().getName());
}
8.补充
定义切入点表达式:语法:
execution(
访问权限
返回值
包名.类名.方法名(方法参数)
异常声明
)
切入点表达式的三个通配符
通配符 意义
* 匹配0个或多个字符
.. 用在包(package)中,表示当前包及其子包
用在方法参数中匹配任意参数
+ 用在类中,匹配当前类及其子类
用在接口中,匹配当前接口及其实现类
举例:
execution(* com.xxx.dao.*.*(..)):匹配dao包下面的所有类的所有方法的任意参数
execution(* com.xxx.service..*.do*(..)):匹配service包及其子包下面的所有类的以do开头的所有方法的任意参数,注意..用在包中后面的类必须为*去匹配所有类,否则可能找不到类而抛异常。
execution(* com.edu.service..*.doSome(Object+)):匹配service包及其子包下面的所有类的doSome方法中的参数为任意引用类型的参数。
9.结果显示
环绕通知的前置增强
前置通知:获得目标类名:com.xxx.open.controller.TAdminController
前置通知:获得目标方法签名:String com.xxx.open.controller.TAdminController.login()
环绕通知的后置增强
后置通知,目标方法的返回值为:hello!