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
我在方法执行后面
环绕后