前文已经讨论了基于配置文件方式实现Spring AOP(Spring AOP - 配置文件方式实现),本文采用注解的方式实现前文相同的功能。配置步骤如下:
1、项目增加aop依赖(pom.xml)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.20.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
2、配置文件增加注解扫描的包(applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描com.text包及子包下的注解-->
<context:component-scan base-package="com.text"/>
</beans>
3、增加切面类(开启切面注解@EnableAspectJAutoProxy、增加切面标识@Aspect)及通知方法(环绕通知@Around,并配置切点表达式execution)
package com.text.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 定义方法切面类
*/
@EnableAspectJAutoProxy //开启AspectJ的注解方式
@Component
@Aspect //标识为切面类
public class MethodAspect {
//配置环绕通知
@Around("execution(public * com.text..*DaoImpl.*(..))")
public void countMethodInvokeTime(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("目标方法执行之前记录初始时间...");
Date startTime = new Date();
try {
proceedingJoinPoint.proceed();//执行目标方法 即:StudentDaoImpl.getById方法
System.out.println("目标方法执行之后记录结束时间...");
String methodName = proceedingJoinPoint.getTarget().getClass().getName() + "." +
proceedingJoinPoint.getSignature().getName();
Date endTime = new Date();
System.out.println(methodName + "方法执行总时长为:" + (endTime.getTime() - startTime.getTime()) + "毫秒");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
4、业务方法StudentDaoImpl
package com.text.dao.impl;
import com.text.dao.StudentDao;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDaoImpl implements StudentDao {
@Override
public void getById(String id) throws Exception {
Thread.sleep(1000);
System.out.println("查询学生id=" + id + "的信息");
}
}
5、测试类Application
package com.text;
import com.text.dao.StudentDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application {
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
StudentDao studentDao = context.getBean("studentDaoImpl", StudentDao.class);
studentDao.getById("1");
System.out.println("======getById end ========");
}
}
6、程序运行结果