最近在公司看到了mybatis与spring整合中MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类。

于是想起了java的动态代理,然后就有了这篇文章。

本文使用动态代理模拟处理事务的拦截器。

接口:

public interface UserService {
public void addUser();
public void removeUser();
public void searchUser();
}

实现类:

public class UserServiceImpl implements UserService {
public void addUser() {
System.out.println("add user");
}
public void removeUser() {
System.out.println("remove user");
}
public void searchUser() {
System.out.println("search user");
}
}

java动态代理的实现有2种方式

1.jdk自带的动态代理

使用jdk自带的动态代理需要了解InvocationHandler接口和Proxy类,他们都是在java.lang.reflect包下。

InvocationHandler介绍:

InvocationHandler是代理实例的调用处理程序实现的接口。

每个代理实例都具有一个关联的InvocationHandler。对代理实例调用方法时,这个方法会调用InvocationHandler的invoke方法。

Proxy介绍:

Proxy 提供静态方法用于创建动态代理类和实例。

实例(模拟AOP处理事务):

public class TransactionInterceptor implements InvocationHandler {

    private Object target;

    public void setTarget(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("start Transaction");
method.invoke(target, args);
System.out.println("end Transaction");
return null;
} }

测试代码:

public class TestDynamicProxy {

    @Test
public void testJDK() {
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
UserService userService = new UserServiceImpl();
transactionInterceptor.setTarget(userService);
UserService userServiceProxy =
(UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
transactionInterceptor);
userServiceProxy.addUser();
} }

测试结果:

start Transaction
add user
end Transaction

很明显,我们通过userServiceProxy这个代理类进行方法调用的时候,会在方法调用前后进行事务的开启和关闭。

2. 第三方库cglib

CGLIB是一个功能强大的,高性能、高质量的代码生成库,用于在运行期扩展Java类和实现Java接口。

它与JDK的动态代理的之间最大的区别就是:

JDK动态代理是针对接口的,而cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

实例:

public class UserServiceCallBack implements MethodInterceptor {

    @Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("start Transaction by cglib");
methodProxy.invokeSuper(o, args);
System.out.println("end Transaction by cglib");
return null;
} }

测试代码:

public class TestDynamicProxy {

    @Test
public void testCGLIB() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(new UserServiceCallBack());
UserServiceImpl proxy = (UserServiceImpl)enhancer.create();
proxy.addUser();
} }

测试结果:

start Transaction by cglib
add user
end Transaction by cglib

结束语

简单讲解了JDK和cglib这2个动态代理,之后会再写篇文章讲讲MapperScannerConfigurer的原理实现。

java动态代理浅析的更多相关文章

  1. Java动态代理简单应用

    概念 代理模式是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. Java动态代理比 ...

  2. Cglib动态代理浅析

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2018-06-29/18.html 作者:夜月归途 出处:http://www.guitu ...

  3. JDK动态代理浅析

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2018-06-29/17.html 作者:夜月归途 出处:http://www.guitu ...

  4. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  5. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  6. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  7. Java 动态代理作用是什么?

    Java 动态代理作用是什么?   1 条评论 分享   默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...

  8. java动态代理原理

    我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...

  9. java 动态代理示例,带主要注释

    Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interf ...

随机推荐

  1. spring中的bean

    环境准备 Eclipse上新建一个简单的maven工程,Artifact Id选择maven-archetype-quickstart: 添加spring-context依赖: <depende ...

  2. Windows Phone Studio-任何人都能开发Windows Phone App的在线工具

    在一段时间的内测以后,微软于今天早些时候发布了其Windows Phone应用开发的在线工具,名字叫做Windows Phone Studio.其意义在于,通过简单的内容添加和样式选择,实现Windo ...

  3. Java Se : Java NIO(服务端)与BIO(客户端)通信

    Java目前有三种IO相关的API了,下面简单的说一下: BIO,阻塞IO,最常用的Java IO API,提供一般的流的读写功能.相信学习Java的人,都用过. NIO,非阻塞IO,在JDK1.4中 ...

  4. DATETIME类型和BIGINT 类型互相转换

    项目中使用BIGINT来存放时间,以下代码用来转换时间类型和BIGINT类型 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ========= ...

  5. Rollback 语句 在08R2版本

    有时候为了数据完整我们会启用到事务.正常的时候一帆风顺,如果rollback 呢? 最简单的一个回滚 IF OBJECT_ID('PROC1') IS NOT NULL     DROP PROCED ...

  6. 为IIS站点添加限制IP

    /// <summary> /// 添加站点限制IP /// </summary> /// <param name="sitename">站点名 ...

  7. 基于RMI服务传输大文件的完整解决方案

    基于RMI服务传输大文件,分为上传和下载两种操作,需要注意的技术点主要有三方面,第一,RMI服务中传输的数据必须是可序列化的.第二,在传输大文件的过程中应该有进度提醒机制,对于大文件传输来说,这点很重 ...

  8. Java api 入门教程 之 JAVA的StringBuffer类

    StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存 ...

  9. Android中设置TextView的颜色setTextColor

    tv.setTextColor(Color.parseColor("#FFFFFF")); tv.setTextColor(Color.WHITE); tv.setTextColo ...

  10. andriod 动态设置TextView 和 RelativeLayou 高度

    XML布局 <RelativeLayout android:id="@+id/rlay_meeting_contact_context" android:layout_wid ...