马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
署理模式
署理模式是一种结构型筹划模式,它答应你提供一个署理对象来控制对另一个对象的访问。署理模式可以在不改变原始对象的环境下,增强或控制对原始对象的访问。署理模式通常用于耽误加载、访问控制、日记记载、性能监控 等场景。
1.静态署理
静态署理是指在编译时就已经确定署理类和被署理类的关系。静态署理通常必要手动编写署理类,而且署理类和被署理类实现类似的接口或继续类似的父类- public interface OrderService {
- void save();
- }
- public class ProxyOrderService implements OrderService {
- // 被代理的对象
- private OrderService orderService;
- public ProxyOrderService(OrderService orderService) {
- this.orderService = orderService;
- }
- // 执行
- public static void main(String[] args) {
- // 创建被代理对象
- OrderService orderService = new OrderServiceImpl();
- // 创建代理对象
- ProxyOrderService proxy = new ProxyOrderService(orderService);
- proxy.save();
- }
- @Override
- public void save() {
- System.out.println("代理前置处理 ...");
- // 执行被代理的对象的方法
- orderService.save();
- System.out.println("代理后置处理 ...");
- }
- }
复制代码 2 动态署理
动态署理是指在运行时动态天生署理类,而不是在编译时手动编写署理类。
2.1 JDK动态署理
JDK动态署理基于Java反射机制实现,它必要被署理对象实现一个接口。- /**
- * 代理对象 实现 InvocationHandler
- * InvocationHandler 该类做方法拦截所用, 通过此类可以对目标方法进行增强
- */
- public class JDKProxyDynamic implements InvocationHandler, Serializable {
- private static final long serialVersionUID = 4431939583048226878L;
- private Object target;
- private Class<?> clazz;
- public JDKProxyDynamic(Class<?> clazz) {
- this.clazz = clazz;
- }
- /**
- * 通过该方法的调用对目标对象进行增强
- */
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("调度真实对象之前,方法名: " + method.getName() + ",参数:" + args);
- // Spring框架中使用动态代理,可以从applicationContext里面获取对应的target对象
- if (Objects.isNull(target)) {
- target = clazz.newInstance();
- }
- System.out.println("代理前置处理 ...");
- Object returnResult = method.invoke(target, args);
- System.out.println("代理后置处理 ...");
- return returnResult;
- }
- public static void main(String[] args) {
- // 创建动态代理对象,JDK动态代理只能代理实现接口的类
- OrderService proxyInstance = (OrderService) Proxy.newProxyInstance(
- OrderServiceImpl.class.getClassLoader(),
- OrderServiceImpl.class.getInterfaces(),
- new JDKProxyDynamic(OrderServiceImpl.class)
- );
- // 通过代理对象调用方法
- proxyInstance.save();
- }
- }
复制代码 2.2 CGLIB动态署理
CGLIB动态署理基于ASM字节码天生框架实现,它不必要被署理对象实现接口。CGLIB动态署理是针对类举行署理的,它通过继续目标类创建子类,并重写目标类的方法。- public class CglibProxy implements MethodInterceptor {
- private static CglibProxy INSTANCE = new CglibProxy();
- private Object target;
- private Class<?> clazz;
- private CglibProxy() {
- }
- public CglibProxy(Class<?> clazz) {
- this.clazz = clazz;
- }
- public static CglibProxy getInstance() {
- return INSTANCE;
- }
- public Object getCglibProxyObject(Object target) {
- // 可以在Spring中获取指定对象,为其创建代理对象,再指定对应的target
- this.clazz = target.getClass();
- this.target = target;
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(target.getClass());
- enhancer.setCallback(this);
- return enhancer.create();
- }
- /**
- * @param object 被代理的对象
- * @param method 被代理对象需要执行的方法
- * @param args 被代理对象需要执行的方法 参数
- * @param proxy 触发父类的方法对象
- * @return 被代理对象需要执行的方法 返回值
- * @throws Throwable 抛出的异常信息
- */
- @Override
- public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- System.out.println("Before method execution: " + method.getName());
- Object result = proxy.invokeSuper(object, args);
- System.out.println("After method execution: " + method.getName());
- return result;
- }
- public static void main(String[] args) {
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(OrderServiceImpl.class);
- enhancer.setCallback(new CglibProxy());
- OrderService orderService = (OrderService) enhancer.create();
- orderService.save();
- }
- }
复制代码 |