设计原则
代理原有对象,添加增强逻辑
静态代理模式
代码
/**
* 接口:租房
*/
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();
}
}
描述
手动创建代理类,通用有局限性。
动态代理模式
JDK实现动态代理
代码
/**
* 接口:租房
*/
public interface IRentingHouse {
void rentHosue();
}
/**
* 委托方(委托对象)
*/
public class RentingHouseImpl implements IRentingHouse {
@Override
public void rentHosue() {
System.out.println("我要租用一室一厅的房子");
}
}
/**
* JdkProxy
* 注意:
* 使用JDK动态代理 委托对象需要实现接口
*/
public class JdkProxy {
public static void main(String[] args) {
IRentingHouse rentingHouse = new RentingHouseImpl(); // 委托对象---委托方
/**
* 参数描述
* ClassLoader loader
* Class<?>[] interfaces 委托对象实现的接口
* InvocationHandler h
*/
IRentingHouse jdkProxy = (IRentingHouse)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;
}
});
// 从代理对象工厂获取代理对象
// IRentingHouse jdkProxy = (IRentingHouse) ProxyFactory.getInstance().getJdkProxy(rentingHouse);
jdkProxy.rentHosue();
}
描述
注意:
使用JDK动态代理 委托对象需要实现接口
CGLIB实现动态代理
代码
/**
* CglibProxy
* 无需实现接口
*/
public class CglibProxy {
public static void main(String[] args) {
RentingHouseImpl rentingHouse = new RentingHouseImpl(); // 委托对象
// 获取rentingHouse对象的代理对象,
// Enhancer类似于JDK动态代理中的Proxy
// 通过实现接口MethodInterceptor能够对各个方法进行拦截增强,类似于JDK动态代理中的InvocationHandler
RentingHouseImpl cglibProxy = (RentingHouseImpl)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;
}
});
// 使用工厂来获取代理对象
// RentingHouseImpl cglibProxy = (RentingHouseImpl) ProxyFactory.getInstance().getCglibProxy(rentingHouse);
cglibProxy.rentHosue();
}
}
描述
无需实现接口
动态代理结合工厂方法
**
* 代理对象工厂:生成代理对象的
*/
public class ProxyFactory {
private ProxyFactory(){ }
private static ProxyFactory proxyFactory = new ProxyFactory();
public static ProxyFactory getInstance() {
return proxyFactory;
}
/**
* Jdk动态代理
* @param obj 委托对象
* @return 代理对象
*/
public Object getJdkProxy(Object obj) {
// 获取代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
// 写增强逻辑
System.out.println("中介(代理)收取服务费3000元");
// 调用原有业务逻辑
result = method.invoke(obj,args);
System.out.println("客户信息卖了3毛钱");
return result;
}
});
}
/**
* 使用cglib动态代理生成代理对象
* @param obj 委托对象
* @return
*/
public Object getCglibProxy(Object obj) {
return Enhancer.create(obj.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(obj,objects);
System.out.println("客户信息卖了3毛钱");
return result;
}
});
}
}
应用场景
spring AOP 、切面 、 事务管理、日志