常用工厂设计模式之代理模式---用几个demo就能理解的代理模式
首先我们要知道,工厂设计模式分为三类:创建型模式、行为型模式、结构型模式
代理模式属于结构型
一、什么是代理
代理模式(Proxy Pattern):一个类代表另一个类的功能
很难懂?
其实用现实生活的话说,简单理解代理就是中介,而代理又分为静态代理和动态代理
但是不管哪种代理都遵循一个前提:
代理要求代理类和被代理类(即目标类)要有共同的行为
那问题又来了,什么又是代理类与目标类的共同行为?
我来告诉你:
- 代理类与目标类实现同一个接口
- 代理类继承目标类
诶,你会发现了,实现接口和继承,不就是多态的体现吗?
没错,说白了就是通过代理类实现目标类里面的方法
下面用几个简单的demo来演示一下
二、静态代理
静态代理:代理类在程序运行之前由程序员在开发过程已经写好了
1、代理类和目标类实现同一个接口
建一个接口
public interface Subject {
public void chuzu();
}
建一个目标类
public class Fangdong implements Subject {
@Override
public void chuzu() {
System.out.println("房屋出租,2000一个月");
}
}
建一个代理类
public class Zhongjie implements Subject{
//目标类的引用
Fangdong fangdong = new Fangdong();
@Override
public void chuzu() {
System.out.println("发布广告");
System.out.println("带客户看房");
//调用目标类方法
fangdong.chuzu();
System.out.println("另收中介费500");
}
}
测试
public class demo1 {
@Test
public void test(){
Subject subject = new Zhongjie();
subject.chuzu();
}
}
运行结果

2、代理类继承目标类
修改一下代理类
public class Zhongjie extends Fangdong{
@Override
public void chuzu() {
System.out.println("发布广告");
System.out.println("带客户看房");
//直接调用父类(目标类)方法
super.chuzu();
System.out.println("另收中介费500");
}
}
修改一下目标类
public class Fangdong {
public void chuzu() {
System.out.println("房屋出租,2000一个月");
}
}
测试
public class demo1 {
@Test
public void test(){
Zhongjie zhongjie = new Zhongjie();
zhongjie.chuzu();
}
}
运行结果

三、动态代理
动态代理:代理类由程序运行过程中态动生成的
1、目标类实现接口—jdk代理
接口
public interface PersonService {
public void insert();
public void update();
public void delete();
}
目标类实现接口
public class PersonServiceImpl implements PersonService{
@Override
public void update() {
System.out.println("执行数据库增加操作");
}
@Override
public void delete() {
System.out.println("执行数据库删除操作");
}
@Override
public void insert() {
System.out.println("执行数据库修改操作");
}
}
JdkProxy代理类(这里相对比较难理解)
public class JdkProxy implements InvocationHandler {
//程序运行中为多个目标类创建对应代理类
private Object target;
//获取目标类
public JdkProxy(Object target){
this.target = target;
}
//为具体某一个目标类创建具体的代理类
public Object createProxy(){
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
//最后一个参数应该传一个InvocationHandler对象,
//为什么这里直接用this,因为JdkProxy本身就是实现InvocationHandler接口,所以这里传它自己
return proxy;
}
@Override
//编写代理类具体的工作流程
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//权限校验
System.out.println("权限校验");
//执行目标类的方法
Object invoke = method.invoke(target, args);
//日志记录
System.out.println("日志记录");
return invoke;
}
}
测试
public class demo2 {
@Test
public void test2(){
JdkProxy jdkProxy = new JdkProxy(new PersonServiceImpl());
PersonService proxy = (PersonService) jdkProxy.createProxy();
proxy.update();
}
}
运行结果

2、目标类没有实现接口—cglib代理
目标类
public class PersonServiceImpl {
public void update() {
System.out.println("执行数据库增加操作");
}
public void delete() {
System.out.println("执行数据库删除操作");
}
public void insert() {
System.out.println("执行数据库修改操作");
}
}
cglib代理类
public class CglibProxy implements InvocationHandler {
private Object target;
//获取到了目标类
public CglibProxy(Object target){
this.target = target;
}
//根据目标类创建代理类
public Object createProxy(){
//使用cglib中的字节码增强类
Enhancer enhancer = new Enhancer();
//代理类需要和目标类有一样的方法
//代理类继承目标类
enhancer.setSuperclass(target.getClass());
//设置代理规则
//因为InvocationHandler 继承了callback接口
//因此当前的规则对象 其实就是 Callback类型的
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("cglib权限校验");
//执行目标类的方法
Object invoke = method.invoke(target, objects);
System.out.println("cglib日志记录");
return invoke;
}
}
测试
@Test
public void test(){
CglibProxy cglibProxy = new CglibProxy(new PersonServiceImpl());
PersonServiceImpl proxy = (PersonServiceImpl) cglibProxy.createProxy();
proxy.update();
}
运行结果

四、由程序自己动态生成的代理类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.sun.proxy;
import com.ujiuye.demo5.PersonService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements PersonService {
private static Method m1;
private static Method m5;
private static Method m2;
private static Method m4;
private static Method m0;
private static Method m3;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void save() throws {
try {
super.h.invoke(this, m5, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void delete() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void update() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m5 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("save");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("delete");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m3 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("update");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
版权声明:本文为weixin_46816383原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。