前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >动态代理

动态代理

作者头像
shaoshaossm
发布2022-12-26 15:39:51
1450
发布2022-12-26 15:39:51
举报
文章被收录于专栏:Java啊
  • 在原有程序不变的情况下通过动态代理增加新的功能(功能增强)
  • 减少代码的重复
  • 专注业务逻辑代码
  • 解耦合,让业务功能和日志,事务非业务功能分离

jdk动态代理实现案例

  • 使用JDK中的Proxy,Method,InvocationHanderl创建对象。
  • JDK动态代理要求目标类必须实现接口

SomeService

代码语言:javascript
复制
public interface SomeService {
    void doSome();
    void doOther();
}

SomeServiceImpl

代码语言:javascript
复制
public class SomeServiceImpl implements SomeService {
    @Override
    public void doSome() {

        System.out.println("执行业务方法doSome");

    }

    @Override
    public void doOther() {

        System.out.println("执行业务方法doOther");

    }

ServiceTools

代码语言:javascript
复制
import java.text.SimpleDateFormat;
import java.util.Date;

public class ServiceTools {
    public static void doLog(){
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        String format = simpleDateFormat.format(date);
        System.out.println("非业务方法,方法的执行时间:"+format);
    }
    public static void doTrans(){
        System.out.println("非业务方法,方法执行完毕后提交事务");
    }

}

MyInvocationHandler

代码语言:javascript
复制
import com.bjpowernode.util.ServiceTools;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 通过代理对象执行方法时,会调用invoke()
        System.out.println("执行了MyInvocationHandler中的invoke()方法");
        String methodName = method.getName(); //doSome , doOther
        Object res = null;
        if ("doSome".equals(methodName)) {
            ServiceTools.doLog();
            res = method.invoke(target, args); //SomeServiceImpl.doOther(), doSome()
            ServiceTools.doTrans();
        } else {
            res = method.invoke(target, args);
        }
        return res;
    }
}

MyApp

代码语言:javascript
复制
import com.bjpowernode.handler.MyInvocationHandler;
import com.bjpowernode.service.SomeService;
import com.bjpowernode.service.impl.SomeServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MyApp {
    public static void main(String[] args) {
        // 使用jdk的Proxy创建代理对象
        SomeService someService = new SomeServiceImpl();
        // 创建InvocationHandler对象
        InvocationHandler invocationHandler = new MyInvocationHandler(someService);
        // 使用Proxy创建代理
        SomeService proxy = (SomeService) Proxy.newProxyInstance(someService.getClass().getClassLoader(),
                someService.getClass().getInterfaces(), invocationHandler);
        // 通过代理执行方法,会调用handler中的invoke()方法
        proxy.doOther();
        System.out.println("------------------------");
        proxy.doSome();
    }
}

运行结果

代码语言:javascript
复制
执行了MyInvocationHandler中的invoke()方法
执行业务方法doOther
------------------------
执行了MyInvocationHandler中的invoke()方法
非业务方法,方法的执行时间:2022-02-24 13:05:12:283
执行业务方法doSome
非业务方法,方法执行完毕后提交事务

CGLB动态代理

  • 第三方工具库,创建代理对象,原理是继承。通过继承目标类,创建子类
  • 子类就是代理对象,要求目标类不能是final的,方法也不能是final的

aspectj

aspectj框架也可实现AOP功能增强,具体可看spring中笔记

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jdk动态代理实现案例
  • CGLB动态代理
  • aspectj
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档