一、基于接口的动态代理(具有共同父接口)
1.1 如何常见代理对象
- 使用
Proxy
类中的newProxyInstance()
方法。
1.2 创建代理对象的要求
- 被代理对象至少<font color="red">实现一个接口</font>,如果没有则不使用。
1.3 newProxyInstance方法的参数
ClassLoader
:类加载器。用于加载代理对象字节码。和被代理对象使用相同的类加载器。固定写法Class[]
:字节码数组。用于让代理对象和被代理对象具有相同的方法。固定写法InvocationHandler
:用于提供增强的代码。如何代理。一般是该接口的实现类,通常为匿名内部类。
1.4 代码示例
1.4.1 被代理对象(实现了接口)
package com.ruki.service.impl;
import com.ruki.service.IPhoneProducer;
public class PhoneProducerImpl implements IPhoneProducer {
public void sellPhone(final float money) {
System.out.println("卖手机了" + money);
}
}
1.4.2 测试
package com.ruki.test;
import com.ruki.service.IPhoneProducer;
import com.ruki.service.impl.PhoneProducerImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PhoneTest {
public static void main(String[] args) {
final IPhoneProducer phoneService = new PhoneProducerImpl();
IPhoneProducer proxyProducer = (IPhoneProducer) Proxy.newProxyInstance(
phoneService.getClass().getClassLoader(),
phoneService.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();//获得方法名
Float payMoney = (Float) args[0];//获得顾客支付的价款
Object rtValue = null;//返回值
if ("sellPhone".equals(name)) {
//如果是卖手机
//没有2000块不卖
if (payMoney > 2000) {
rtValue = method.invoke(phoneService, payMoney / 2);
}
}
return rtValue;
}
}
);
proxyProducer.sellPhone(4000f);
}
}
二、基于子类的动态代理(代理继承被代理)
- 需要使用第三方jar包,
cglib
2.1 如何创建代理对象
- 使用
Enhancer
类中的create()
方法
2.2 创建代理对象的要求
- 被代理对象<font color="red">不能是最终类</font>,即不能被
final
修饰
2.3 create方法的参数
class
:字节码。指定被代理对象的字节码MethodInterceptor
:拦截器指定如何代理
2.4 代码示例
2.4.1 被代理对象
package com.ruki.service.pojo;
public class PhoneProducerPojo {
public void sellPhone(final float money) {
System.out.println("卖手机了" + money);
}
}
2.4.2 测试
package com.ruki.test;
import com.ruki.service.PhoneProducerPojo;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class PhoneTest2 {
public static void main(String[] args) {
final PhoneProducerPojo phoneProducer = new PhoneProducerPojo();//被代理
PhoneProducerPojo cglibPhoneProducer = (PhoneProducerPojo) Enhancer.create(phoneProducer.getClass(), new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
String methodName = method.getName();//获得方法名
Float money = (Float) args[0];//获得参数
Object rtValue = null;//初始化返回值
if ("sellPhone".equals(methodName)) {
if (money > 1000f) {
rtValue = method.invoke(PhoneProducerPojo, money / 2);
}
}
return rtValue;
}
});
cglibPhoneProducer.sellPhone(2000f);
}
}