案例设定:测定接口执行效率
简化设定:在接口执行前输出当前系统时间
开发模式: XML or 注解
目录结构:

思路分析:
- 其中context依赖了aop
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-contextartifactId>
- <version>5.2.10.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.aspectjgroupId>
- <artifactId>aspectjweaverartifactId>
- <version>1.9.4version>
- dependency>
- @Repository
- public class BookDaoImpl implements BookDao {
-
- public void save() {
- System.out.println(System.currentTimeMillis());
- System.out.println("book dao save...");
-
- }
-
- @Override
- public void update() {
- System.out.println("book dao update...");
- }
- }
- public class MyAdvice {
-
- public void method(){
- System.out.println(System.currentTimeMillis());
- }
- }
- public class MyAdvice {
-
- //制作切入点
- @Pointcut("execution(void com.hyk.dao.BookDao.update())")
- private void pt(){
-
- }
- //制作共性功能
- public void method(){
- System.out.println(System.currentTimeMillis());
- }
- }
- public class MyAdvice {
-
- //制作切入点
- @Pointcut("execution(void com.hyk.dao.BookDao.update())")
- private void pt(){
-
- }
- //制作共性功能
- @Before("pt()")
- public void method(){
- System.out.println(System.currentTimeMillis());
- }
- }
目标对象( Target ) : 原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的
代理( Proxy ) :目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现
切入点:要进行增强的方法
切入点表达式:要进行增强的方法的描述方式
execution(void com.hyk.dao.BookDao.update())
描述方式一:执行com.hyk.dao包下的BookDao接口中的无参数update方法
execution(void com.hyk.dao.impl.BookDaoImpl.update())
描述方式一:执行com.hyk.dao.impl包下的BookDaoImpl接口中的无参数update方法
描述实现类和描述接口的都是OK的
切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数) 异常名)
可以使用通配符描述切入点,快速描述
- execution(public * com.hyk.*.UserService.find*(*))
- 匹配com.hyk包下的任意包中的UserService类或者接口中所有find开头的带有一个参数的方法
- execution(public User com..UserService.findById(..))
- 匹配com包下的任意包中的UserService类或者接口中所有名称为findById的方法
- execution(* *..*Service+.*(..))
- @Before("pt()")
- public void before(){
- System.out.println(
- "before......."
- );
- }
- @After("pt()")
- public void after(){
- System.out.println(
- "after......."
- );
- }
- @Around("pt()")
- public Object around(ProceedingJoinPoint pjp) throws Throwable {
- System.out.println(
- "around before......."
- );
- //表示对原始操作的调用
- Object proceed = pjp.proceed();
- System.out.println(
- "around after......."
- );
- return proceed;
- }
- @AfterReturning("pt()")
- public void afterReturning(){
- System.out.println(
- "afterReturning......."
- );
- }
- @AfterThrowing("pt()")
- public void afterThrowing(){
- System.out.println(
- "afterThrowing......."
- );
- }
- around before.......
- before.......
- book dao update...
- afterReturning.......
- after.......
- around after.......
-
- Process finished with exit code 0
@Around注意事项

AOP类代码:
- @Component
- @Aspect
- public class ProjectAdvice {
-
- //匹配业务层的所有方法
- @Pointcut("execution(* com.hyk.service.*Service.*(..))")
- private void servicePoint(){
-
- }
-
- @Around("ProjectAdvice.servicePoint()")
- public void runSpeed(ProceedingJoinPoint proceedingJoinPointp) throws Throwable {
- //获取一次执行的签名信息
- Signature signature = proceedingJoinPointp.getSignature();
- //类型名
- String className = signature.getDeclaringTypeName();
- //方法名
- String methodName =signature.getName();
- //获取开始时间
- long startTime=System.currentTimeMillis();
- for (int i =0;i<10000;i++){
- Object proceed = proceedingJoinPointp.proceed();
- }
- //获取结束时间
- long endTime=System.currentTimeMillis();
- System.out.println(className+"."+methodName+"执行万次运行时间: "+(endTime-startTime)+"ms");
- }
- }
执行结果:
com.hyk.service.UserService.findById执行万次运行时间: 4530ms
nullProcess finished with exit code 0