avatar

SpringAOP-2

  1. 使用AOP前,先了解下JavaProxy和Cglib的用法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.springboot;

import com.wzl.entity.UserService;
import com.wzl.entity.UserServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* wzl 动态代理的测试类
*/
public class JavaProxyTest {
public static void main(String[] args) {
final UserServiceImpl userServiceImpl = new UserServiceImpl();
UserService userService = (UserService) Proxy.newProxyInstance(JavaProxyTest.class.getClassLoader(),
new Class[]{UserService.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置通知");
try {
method.invoke(userServiceImpl, args);
} catch (IllegalAccessException e) {
System.out.println("异常通知");
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("后置通知");
return null;
}
});
userService.getName();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.example.springboot;

import com.wzl.entity.UserService;
import com.wzl.entity.UserServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
* @ClassName CglibTest
* @Description CglibTest
* @Author wuzhilang
* @Date 2020/3/30 21:27
* @Version 1.0
*/
public class CglibTest {
public static void main(String[] args) {
UserServiceImpl userServiceImpl = new UserServiceImpl();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("前置方法");
Object result = null;
try {
result = methodProxy.invoke(userServiceImpl, objects);
} catch (Throwable throwable) {
System.out.println("异常通知");
throwable.printStackTrace();
}
System.out.println("后置方法");
return result;
}
});
UserService userService = (UserService) enhancer.create();
userService.getName();
}
}

SpringAop的写法

1
2
3
4
5
6
public void createProxyTest(){
Object target = new UserServiceImpl();
ProxyFactory pf = new ProxyFactory(target);
UserService service = (UserService)pf.getProxy();
service.getName();
}

看下效果

我在UserServiceImpl的方法里写了

1
2
3
4
@Override
public void getName() {
System.out.printf("My Name is Tom");
}

看下控制台的输出

高级用法 通过设置表达式

1
2
3
4
5
6
7
8
9
10
public void createProxyAspectByTest(){
Object target = new UserServiceImpl();
AspectJProxyFactory pf = new AspectJProxyFactory(target);
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression("execution(* *.getName(..))");
pf.addAdvisor(advisor);
UserService service = (UserService)pf.getProxy();
service.getName();
service.setName();
}

分析下这张图:

addAdvisor 添加通知

Advisor和pointcut 添加适配器

getProxy生成Prox createAopProxy

一个需要注意的地方:根据接口或者配置来决定是否使用JavaProxy

文章作者: 无知的小狼
文章链接: https://bytedance.press/2020/04/06/20200401/SpringAOP-2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 无知的小狼

评论