SpringAOP的三种实现方式总结


SpringAOP的实现方式

1.使用原生SpringApi接口实现AOP:

  • 首先我们写个UserService接口和它的实现类

    public interface UserService {
        public void add();
    }
    
    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("add user");
        }
    }
    
  • 在applicationConte.xml导入命名空间。先搞切入点,再在切入点把Log.java切入进去。

    
    
    

    

        


        
        
    
  • 前置和后置的Log
Log.java:
public class Log implements MethodBeforeAdvice {
    // method:方法
    //objects:参数
    //o:对象
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");//某某对象的方法被执行了
    }
}


AfterLog.java:    
package com.zhou.log;

public class AfterLog implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"返回的结果为"+returnValue);
    }
}
  • 测试代码如下
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //PS:动态代理的是接口
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
    //报错了 因为没导入aspect依赖
}
  • 输出结果

com.zhou.service.UserServiceImpl的add被执行了
add user
执行了add返回的结果为null

2.自定义类实现AOP

  • 先写一个简单MyPointCut类

    public class MyPointCut {
    
        public void before(){
            System.out.println("我在方法执行前面");
        }
    
        public void after(){
            System.out.println("我在方法执行后面");
        }
    }
    
  • 另一种方式配置applicationConte.xml

    
        
        
    
            
    
            
    
                
                
            
        
    
  • 测试一下

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
    
        }
    }
    

    输出结果:

    ? 我在方法执行前面
    ? add user
    ? 我在方法执行后面

  • execution表达式:

    
    
    * 表示返回值的类型任意
    com.zhou.service.UserServiceImpl 横切的业务类路径
    .* 代表这个类下的所有方法
    (..) ()代表参数,两个点代表可以有任意参数

    3.使用注解实现AOP

  • MyPointCut.java

    @Aspect
    public class AnnotationPointCut {
        @Before("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void before() {
            System.out.println("我在方法执行前面");
        }
    
        @After("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void after() {
            System.out.println("我在方法执行后面");
        }
    
    
  • 关于环绕(@Around)

        //在环绕增强中 我们可以给定一个参数 代表我们要处理切入的点 JointPoint:与切入点匹配的执行点
        @Around("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("环绕前");
            Object proceed = joinPoint.proceed();//执行方法
            System.out.println("环绕后");
    
            //Signature signature = joinPoint.getSignature();
            //System.out.println("signature:" + signature.toString());
        }
    }
    
  • 配置文件

    
        
    
        
    
  • 输出结果:看看顺序= =

    环绕前
    我在方法执行前面
    add user
    我在方法执行后面
    环绕后