# AOP中的代理模式应用
# 8 AOP的底层原理-JDK的动态代理
从JDK1.2之后,引入了反射机制,其中反射机制中有一个特殊的功能,就是可以根据要实现的接口按照这个接口的结构自动的去生成响应的代理类,完成目标方法的扩展工作,这个过程中因为代理类是通过反射自动在运行时生成的,所以称之为:动态代理
静态代理与动态代理最显著的区别:静态代理需要手写代理类,而动态代理是根据我们接口的结构自动的在运行时内存中生成
# JDK动态代理示例代码
package com.torey.spring.service;
/**
* @Author http://torey611.gitee.io/li-tao-feng/
* @Email torey6061@qq.com
* @Date 2021/5/2 18:51
* @描述:
*/
public interface EmployeeService {
void createEmployee();
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
package com.torey.spring.service;
/**
* @Author http://torey611.gitee.io/li-tao-feng/
* @Email torey6061@qq.com
* @Date 2021/5/2 18:52
* @描述:
*/
public class EmployeeServiceImpl implements EmployeeService {
public void createEmployee() {
System.out.println(this.getClass().getName() + ".createEmployee()");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
package com.torey.spring.service;
/**
* @Author http://torey611.gitee.io/li-tao-feng/
* @Email torey6061@qq.com
* @Date 2021/5/2 18:20
* @描述:
*/
public interface UserService {
void createUser();
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
package com.torey.spring.service;
/**
* @Author http://torey611.gitee.io/li-tao-feng/
* @Email torey6061@qq.com
* @Date 2021/5/2 18:21
* @描述:
*/
public class UserServiceImpl implements UserService {
public void createUser() {
System.out.println(this.getClass().getName() + ".createUser();执行添加用户逻辑");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
package com.torey.spring.service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author http://torey611.gitee.io/li-tao-feng/
* @Email torey6061@qq.com
* @Date 2021/5/2 18:23
* @描述: InvocationHandler是JDK提供的反射类,用于在JDK动态代理中对目标方法进行增强
* InvocationHandler实现类与切面类的环绕通知类似
*/
public class ProxyInvocationHandler implements InvocationHandler {
//目标对象
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
/**
* 在invoke方法对目标方法进行增强
* @param proxy 代理类对象
* @param method 目标方法对象
* @param args 目标方法实参
* @return 目标方法运行后返回值
* @throws Throwable 目标方法抛出的异常
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(this.getClass().getName() + "invoke();方法执行前:前置通知");
Object ret = method.invoke(this.target, args);
System.out.println(this.getClass().getName() + "invoke();方法执行后:后置通知");
return ret;
}
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
//动态创建代理类
//动态代理,必须实现接口才可以运行
//Proxy.newProxyInstance 根据已有的接口,来生成代理类
UserService userServiceProxy=(UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new ProxyInvocationHandler(userService));
userServiceProxy.createUser();
System.out.println("======================");
EmployeeService employeeService= new EmployeeServiceImpl();
EmployeeService employeeServiceProxy= (EmployeeService)Proxy.newProxyInstance(employeeService.getClass().getClassLoader(),
employeeService.getClass().getInterfaces(),
new ProxyInvocationHandler(employeeService));
employeeServiceProxy.createEmployee();
}
}
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
42
43
44
45
46
47
48
49
50
51
52
53
54
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
42
43
44
45
46
47
48
49
50
51
52
53
54
# 导航,上一页,下一页
# 支持我-微信扫一扫-加入微信公众号
# 赞赏作者
# 种一棵树,最好的时间是十年前,其次是现在
立志用功,如种树然。方其根芽,犹未有干;及其有干,尚未有枝;枝而后叶,叶而后花、实。初种根时,只管栽培灌溉,勿作枝想,勿作实想。悬想何益?何不忘栽培之功,怕没有枝叶花实?