1.引出
针对第八篇中使用继承实现增强环绕的不足,可通过引入Java代理设计模式进行优化。代理模式作为结构型设计模式之一,其核心在于通过代理类在不修改目标类(被代理类)原有代码的前提下实现功能增强。
2.代理模式包含三个关键要素:
- 抽象接口(如OrderService)
- 目标类(如OrderServiceImpl)
- 代理类(作为功能增强的执行者)
实现要点:
- 代理类需持有被代理类对象的引用
- 在代理类中实现增强逻辑
3.代理模式有两种实现方式:
静态代理:
- 特点:代理关系在编译期确定,扩展性较差
- 适用场景:适用于简单功能增强或修改需求较少的场景
动态代理:
- 特点:代理类在运行时动态生成,通过反射机制实现方法增强
动态代理又分为两种实现:
JDK动态代理:
- 要求:被代理类必须实现至少一个接口
- 特点:Java原生支持,无需额外依赖
CGLIB动态代理:
- 要求:被代理类无需实现接口
- 特点:需引入第三方库支持
4.静态代理实现方法增强
OrderService接口:
java
public interface OrderService {
//用户下订单方法
void createOrder(String username,double money);
}
OrderServiceImpl实现类:
java
public class OrderServiceImpl implements OrderService {
/**
* 实现用户下订单实际方法
* @param username 用户名
* @param money //金额
*/
@Override
public void createOrder(String username, double money) {
System.out.println(" 用户 下订单 .... ");
}
}
创建代理类
使用构造器的思想进行赋值,也可以使用set进行赋值
java
package com.wn.service.impl;
import com.wn.service.OrderService;
/**
* 演示静态代理实现对目标类方法进行增强
* //1.代理类实现的目标类相同接口
*/
public class StaticProxy implements OrderService{
//2.持有被代理类的对象的引用
private OrderService orderService;
public StaticProxy(OrderService orderService){
this.orderService = orderService;
}
/**
* 重写接口中方法
*/
@Override
public void createOrder(String username, double money) {
//1.前置增强
System.out.println(" 参数 校验 ");
//调用目标类中方法
orderService.createOrder(username, money);
//2.后置增强
System.out.println(" 记录 日志 ");
}
}
测试类
java
public class OrderServiceTest {
public static void main(String[] args) {
//1.测试 对应下订单 方法进行前置和后置增强
OrderService orderService = new OrderServiceImpl();
//2.创建代理类对象
StaticProxy proxy = new StaticProxy(orderService);
proxy.createOrder("张三", 199);
}
}
5.JDK动态代理
实现JDK动态代理Java中使用Proxy类实现
在Proxy类中,可通过newProxyInstance静态方法创建代理对象。该方法接收三个关键参数:
ClassLoader loader:用于加载目标类接口的类加载器Class[] interfaces:目标类实现的接口的字节码对象数组InvocationHandler h:包含核心业务增强逻辑的处理器参数
InvocationHandler接口方法参数说明:
Object invoke(Object proxy, Method method, Object[] args)
参数说明:
- proxy:生成的代理对象实例(通常无需使用)
- method:当前被调用的Method对象
- args:方法调用时传入的参数数组
使用Proxy实现创建代理对象,并对目标类中指定方法进行增强。
在测试类中使用案例:
java
public class OrderServiceTest {
public static void main(String[] args) {
//1.测试 对应下订单 方法进行前置和后置增强
OrderService orderService = new OrderServiceImpl();
//3.使用Java中Proxy类创建目标类代理对象,并完成对象指定方法进行增强
/**
* 参数1: 表示类加载器
* 参数2:字节码对象数组
* 参数3:执行器对象
*/
OrderService proxy = (OrderService) Proxy.newProxyInstance(orderService.getClass().getClassLoader(), orderService.getClass().getInterfaces(), new InvocationHandler() {
/**
* 参数1:表示代理对象
* 参数2:表示目标对象的方法的Method对象
* 参数3:表示目标方法参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.获取方法名称
Object result = null;
if(method.getName().equals("createOrder")){
//增强
System.out.println("********参数校验********");
//1.执行方法
/**
* 参数1:表示目标对象
* 参数2:表示执行方法的实际参数
*/
result = method.invoke(orderService, args);
System.out.println("------日志记录----");
}else {
//不需要增强
result= method.invoke(orderService, args);
}
return result;
}
});
//通过代理对象调用 下订单方法
proxy.createOrder("菲菲", 88);
System.out.println(proxy.deleteById(2222));
}
}