什么是动态代理?动态代理有哪些应用?如何编写动态代理案例

什么是动态代理?

当我们需要给某个类或者接口中的方法添加一些额外的功能比如日志、事务的时候,可以通过创建一个代理类来实现这些功能;该代理类既包含了原有类的完整功能,同时在这些功能的基础上添加了其他的逻辑。这个代理类不是事先定义好的,而是动态生成的,比较灵活;

有几种动态代理

1.java动态代理

    java动态代理有个缺点就是要被代理的类必须实现一个接口,否则没法代理

2.cglib动态代理

   cglib动态代理可以对没有实现接口的类进行代理

动态代理的应用

AOP

在我们用到spring框架的时候碰到的aop前置后置通知都是基于动态代理来实现的,这里不细追。

如何编写动态代理案例?

我们使用java的动态代理来编写一个案例,主要分为以下几步:

1.编写一个常规方法的接口,这里我们定义一个用户接口,并且编写保存用户方法save()

/**
 * 用户接口
 */
public interface UserDao {
    public void save();//定义保存用户的方法
}

2.编写用户接口的实现类,并且实现接口方法save()

/**
*  用户接口实现类
*/
public class UserDaoImp implements UserDao {
    @Override
    public void save() {
        System.out.println("保存用户");
        System.out.println("保存成功啦");
    }
}

3.编写自己的MyInvocationHandler实现InvocationHandler接口,重写invoke方法来添加我们需要添加的额外功能

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 {
        System.out.println("开始记录日志,方法开始执行...");
        method.invoke(target,args);
        System.out.println("结束记录日志,方法结束执行...");
        return null;
    }
}

4.通过Proxy来生成代理对象,有俩种方式

public static void main(String[] args) throws Exception {
    /**
     * 方式一
     */
    //通过调用动态代理类Proxy的newProxyInstance()生成代理对象
    UserDao userDao= (UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(),
            new Class<?>[] { UserDao.class }, // 被代理类的接口
            new MyInvocationHandler(new UserDaoImp()));//要被代理的对象
    userDao.save();
    /**
     * 方式二
     */
    //编写invocationhandler实现额外功能
    InvocationHandler handler = new MyInvocationHandler(new UserDaoImp());
    //通过调用动态代理类Proxy的getProxyClass()方法获取要代理的类
    Class<?> proxyClass = Proxy.getProxyClass(UserDao.class.getClassLoader(), UserDao.class);
    //通过代理类生成代理对象
    UserDao userDao1 = (UserDao) proxyClass.getConstructor(InvocationHandler.class).
            newInstance(handler);
    userDao1.save();

}

运行结果如下所示:

 

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值