大家好,我们学习了 AOP 的概念,理解了 AOP 的作用,明白了什么是 AOP 面向切面编程,目的是进行解耦,可以自由地对某个功能方法做增强,而它的设计模式就是代理模式。
那么本小节我们就学习 AOP 设计模式之代理模式,明白代理模式的含义,掌握代理模式的语法,同时明白它的应用场景。
代理名词解释为:以被代理人名义,在授权范围内与第三方实施行为。而在软件行业中代理模式是一种非常常用的设计模式,跟现实生活中的逻辑一致。
在开发中代理模式的表现为:我们创建带有现有对象的代理对象,以便向外界提供功能接口。代理对象可以在客户端和目标对象之间起到中介的作用。
中介什么作用? 可以为被代理对象执行一些附带的,增加的额外功能。
代理模式图例:
图例解释
上面已经解释了代理模式的概念和原理,在开发中,实现代理模式可以分为两种。
下面,我们就针对这两种模式演示效果… 各位看官随我来。
1.userService 接口代码
public interface UserService {
public void saveUser();
}
2.userServiceImpl 实现类代码
@Service
public class UserServiceImpl implements UserService {
public void saveUser() {
System.out.println("执行service中的保存逻辑");
}
}
3.userServiceProxy 代理类代码
public class UserServiceProxy implements UserService {
//被代理类实现接口
private UserService userService;
public UserServiceProxy(UserService userService) {
this.userService = userService;
}
//覆写的方法
@Override
public void saveUser() {
System.out.println("原始功能执行之前的逻辑代码");
userService.saveUser();;
System.out.println("原始功能执行之后的逻辑代码");
}
}
代码解释:
userService
接口和 userServiceImpl
实现类代码不做赘述,已经用过多次。
重点关注于在 userServiceProxy
代理类代码,其中属性为被代理类的接口,目的是传入进来被代理类实例,对它做功能增强。
下面的 saveUser
方法是代理类执行的逻辑,在方法内部有增强的代码逻辑,也保留了原始实例的代码功能。
4. 测试代码
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(SpringConfig.class);
context.refresh();
//获取接口实例
UserService service = context.getBean(UserService.class);
//创建实例的代理
UserServiceProxy proxy = new UserServiceProxy(service);
//执行方法
proxy.saveUser();
}
5. 测试结果
可以看到,执行结果中即包含了被代理对象的原始保存方法的逻辑,也有代理类中对原始方法的两个增强代码。
1. 创建动态处理器
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(final Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行前逻辑");
Object result = method.invoke(object, args);
System.out.println("执行后逻辑");
return result;
}
}
2. 测试类代码
public class SpringTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(SpringConfig.class);
context.refresh();
//获取接口实例
UserService service = context.getBean(UserService.class);
//动态创建实例的代理
UserService proxy = (UserService)Proxy.newProxyInstance(UserService.class.getClassLoader(),
new Class[]{UserService.class}, new DynamicProxy(service));
//proxy执行方法
proxy.saveUser();
}
}
代码解释
Proxy.newProxyInstance
是 JDK 提供的一个用于动态创建代理实例的方法,JDK 1.7 的 API 有如下说明:
红线框的内部是简易方式创建代理对象的方式,也就是我们示例中代码的实现方式,参数解释如下:
3. 测试结果
本小节学习了代理模式以及它的的实现,那么要求大家掌握的内容如下:
1. 实现要素
被代理类最少实现一个接口。
2. 实现步骤
newProxyInstance
方法获取代理类实例;0/1000