代理模式:静态代理,动态代理

代理设计模式的思想:

代理原有对象,添加增强逻辑
举个例子,我们租房可以自己找房源,也可以找中介,中介就相当于代理。

静态代理模式

/**
* 接口:租房
*/
public interface IRentingHouse {
     
   void rentHosue();
}
/**
* 委托类
*/
public class RentingHouseImpl implements IRentingHouse {
     
   @Override
   public void rentHosue() {
     
       System.out.println("我要租用一室一厅的房子");
   }
}
/**
* 代理类  
静态代理,实时在在的需要创建代理类,为每一个需要代理的类创建一个代理类;
动态代理就不需要为每一个类去创建动态代理类
*/
public class RentingHouseProxy implements IRentingHouse {
     
   private IRentingHouse rentingHouse;
   public RentingHouseProxy(IRentingHouse rentingHouse) {
     
       this.rentingHouse = rentingHouse;
   }
   @Override
   public void rentHosue() {
     
       System.out.println("中介(代理)收取服务费3000元");
       rentingHouse.rentHosue();
       System.out.println("客户信息卖了3毛钱");
   }
}
/**
* 调用
*/
public class Test {
     
   public static void main(String[] args) {
     
       IRentingHouse rentingHouse = new RentingHouseImpl();
       // 自己要租用一个一室一厅的房子
       // rentingHouse.rentHosue();
       RentingHouseProxy rentingHouseProxy = new RentingHouseProxy(rentingHouse);
       rentingHouseProxy.rentHosue();
   }
}
中介(代理)收取服务费3000元
我要租用一室一厅的房子
客户信息卖了3毛钱......

动态代理模式

JDK实现动态代理

package nia.chapter2.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * @author Jm
 * @date 2021/4/30
 * 代理工长类
 */
public class ProxyFactory {
     
    private ProxyFactory(){
     }
    // 饿汉模式的单例
    private static ProxyFactory proxyFactory = new ProxyFactory();
    public static ProxyFactory getInstance() {
     
        return proxyFactory;
    }
    /**
     * JDK动态代理
     * 注意:
     * 使用JDK动态代理 委托对象需要实现接口!!
     */
    public Object getJDKProxy(IRentingHouse rentingHouse) {
     
        return Proxy.newProxyInstance(rentingHouse.getClass().getClassLoader(),
                rentingHouse.getClass().getInterfaces(),
                new InvocationHandler() {
     
                    /**
                     * @param proxy 代理对象
                     * @param method  调用的方法
                     * @param args 调用方法的参数
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     
                        Object result = null;
                        // 写增强逻辑
                        System.out.println("中介(代理)收取服务费3000元");
                        result = method.invoke(rentingHouse, args); // 调用原有业务逻辑
                        System.out.println("客户信息卖了3毛钱......");
                        return result;
                    }
                });
    }
}
package nia.chapter2.proxy;
/**
 * JDK动态代理
 * 注意:
 * 使用JDK动态代理 委托对象需要实现接口!!
 */
public class ProxyFactoryTest {
     
    public static void main(String[] args) {
     
        IRentingHouse rentingHouse = new RentingHouseImpl();
        // 从代理对象工厂获取代理对象
        IRentingHouse jdkProxy = (IRentingHouse) ProxyFactory.getInstance().getJDKProxy(rentingHouse);
        jdkProxy.rentHosue();
    }
}
中介(代理)收取服务费3000元
我要租用一室一厅的房子
客户信息卖了3毛钱......

CGLIB实现动态代理

package nia.chapter2.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * @author MJ
 * @date 2021/4/30
 */
public class ProxyFactory {
     
    private ProxyFactory(){
     }
    // 饿汉模式的单例
    private static ProxyFactory proxyFactory = new ProxyFactory();
    public static ProxyFactory getInstance() {
     
        return proxyFactory;
    }
    /**
     * cglib动态代理
     * 注意:无需实现接口
     * 但是需要引入第三方jar包,该功能是第三方实现的
     
     
         cglib
         cglib
         3.3.0
     
     */
    public Object getCglibProxy(IRentingHouse rentingHouse) {
     
        return Enhancer.create(rentingHouse.getClass(), new MethodInterceptor() {
     
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
     
                Object result = null;
                System.out.println("中介(代理)收取服务费3000元");
                result = method.invoke(rentingHouse, objects); // 调用原有业务逻辑
                System.out.println("客户信息卖了3毛钱......");
                return result;
            }
        });
    }
}
package nia.chapter2.proxy;
/**
 * JDK动态代理
 * 注意:
 * 使用JDK动态代理 委托对象需要实现接口!!
 */
public class ProxyFactoryTest {
     
    public static void main(String[] args) {
     
        IRentingHouse rentingHouse = new RentingHouseImpl();
        IRentingHouse cglibProxy = (IRentingHouse) ProxyFactory.getInstance().getCglibProxy(rentingHouse);
        cglibProxy.rentHosue();
    }
}
中介(代理)收取服务费3000元
我要租用一室一厅的房子
客户信息卖了3毛钱......

JDK和CGLIB实现动态代理的区别

• JDK动态代理必须要实现接口
• cglib是第三方jar包提供的要使用必须进入第三方jar包,cglib不需要实现接口;

应用场景

spring AOP 、切面 、 事务管理、日志

你可能感兴趣的:(Spring,jdk动态代理,cglib动态代理,动态代理,静态代理)