简介
- Proxy代理模式是一种结构型设计模式。通过代理模式可以实现程序之间的解耦,可以解决在直接访问对象时带来的程序之间耦合度增大的问题。
- 按照代理的创建时期,代理类分为两种:
- 静态代理:在编译期,手动创建代理类,而不是由编译器生成代理类。
- 动态代理:在运行期,运用反射机制动态而生成代理类。
静态代理
- 优点
- 静态代理可以将目标类和目标方法封装起来,有隐蔽的作用。
- 缺点
- 静态代理类只能为特定的接口服务。
- 如想要为多个接口服务则需要建立很多个代理类。
目录结构
- cn.water
- main
- java
- IProducer.java(接口)
- Producer.java(实现类)
- ProxyProducer.java(代理类)
- test
接口
IProducer.java
package cn.water.StaticProxy;
public interface IProducer {
void saleProduct(float money);
void afterService(float money);
}
实现类
Producer.java
package cn.water.StaticProxy;
public class Producer implements IProducer {
public void saleProduct(float money) {
System.out.println("生产者:通过[销售],获得了"+money+"元");
}
public void afterService(float money) {
System.out.println("生产者:通过[售后],获得了"+money+"元");
}
}
代理类
ProxyProducer.java
package cn.water.StaticProxy;
public class ProxyProducer implements IProducer {
private Producer producer = new Producer();
public void saleProduct(float money) {
System.out.println("消费者:消费了"+money+"元");
producer.saleProduct(money * 0.2f);
}
public void afterService(float money) {
System.out.println("消费者:消费了"+money+"元");
producer.afterService(2);
}
}
测试类
staticTest.java
package cn.water.test;
import cn.water.StaticProxy.IProducer;
import cn.water.StaticProxy.Producer;
import cn.water.StaticProxy.ProxyProducer;
import org.junit.Test;
public class staticTest {
@Test
public void test(){
final Producer producer = new Producer();
IProducer proxy = new ProxyProducer() ;
proxy.saleProduct(999.12f);
proxy.afterService(99f);
}
}
动态代理(JDK)
- JDK动态代理基于 Java的反射机制 实现。
- 因为Java的反射机制基于接口,所以目标类一定要有接口。
- 基于JDK技术动态代理类技术核心:Proxy类 和 InvocationHandler接口。(java.lang.reflect)
- Proxy类中定义了生成JDK动态代理类的方法
getProxyClass(ClassLoader loader,Class... interfaces)
,返回class实例代表一个class文件。生成的动态代理类继承Proxy类(重要特性) ,并实现公共接口。
- InvocationHandler接口 是被动态代理类回调的接口,我们所有需要增加的处理逻辑都添加到 invoke方法里面。
- 匿名内部类参数必须为final类型
目录结构
- cn.water
- IProducer.java(接口)
- Producer.java(实现类)
- test
接口
IProducer.java
package cn.water.DynamicProxy.jdk;
public interface IProducer {
void saleProduct(float money);
void afterService(float money);
}
实现类
Producer.java
package cn.water.DynamicProxy.jdk;
public class Producer implements IProducer {
public void saleProduct(float money) {
System.out.println("生产者:通过[销售],获得了"+money+"元");
}
public void afterService(float money) {
System.out.println("生产者:通过[售后],获得了"+money+"元");
}
}
测试类
staticTest.java
- Proxy.newProxyInstance方法
- 加载器
- 接口
- InvocationHandler接口
- 匿名内部类只能访问方法内修饰符为final的参数
package cn.water.test;
import cn.water.DynamicProxy.jdk.IProducer;
import cn.water.DynamicProxy.jdk.Producer;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class jdkTest {
@Test
public void test(){
final Producer producer = new Producer();
IProducer proxy = (IProducer) Proxy.newProxyInstance(
producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
Float money = (Float) args[0];
if ("saleProduct".equals(method.getName())) {
System.out.println("消费者:消费了"+money+"元");
result = method.invoke(producer, money * 0.2f);
}
if ("afterService".equals(method.getName())) {
System.out.println("消费者:消费了"+money+"元");
result = method.invoke(producer, 5);
}
return result;
}
}
);
proxy.saleProduct(999.12f);
proxy.afterService(999.12f);
}
}
动态代理(cglib)
目录结构
实现类
Producer.java
package cn.water.DynamicProxy.cglib;
import cn.water.DynamicProxy.jdk.IProducer;
public class Producer {
public void saleProduct(float money) {
System.out.println("生产者:通过[销售],获得了"+money+"元");
}
public void afterService(float money) {
System.out.println("生产者:通过[售后],获得了"+money+"元");
}
}
测试类
staticTest.java
package cn.water.test;
import cn.water.DynamicProxy.cglib.Producer;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
public class cglibTest {
@Test
public void test() {
final Producer producer = new Producer();
Producer cglibProducer = (Producer) Enhancer.create(
producer.getClass(),
new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result = null;
Float money = (Float) args[0];
if ("saleProduct".equals(method.getName())) {
System.out.println("消费者:消费了"+money+"元");
result = method.invoke(producer, money * 0.2f);
}
if ("afterService".equals(method.getName())) {
System.out.println("消费者:消费了"+money+"元");
result = method.invoke(producer, 5);
}
return result;
}
});
cglibProducer.saleProduct(999.12f);
cglibProducer.afterService(999.12f);
}
}