主要目标理解JDK动态代理
1、为什么要使用代理
实际程序中,有许多程序的共同操作和实际业务没有关系,但是我们有不得不每次把这些相同的代码给他加上去
显然我们可以把这样的操作当成一个切面,在执行方法之前和之后去调用这样一段特殊的代码,从而实现需要的
功能。
*日志处理:比如操作日志可能只是需要保存执行的方法、时间等信息,所以这样的功能应当被当做成一个切面
在执行方法的时候或者执行完之后加上对该方法的执行日志
*权限处理:只执行某个方法的时候,可能需要检查当前用户是否有权限执行改操作,可以把权限检测当当成一个
切面,在需要的时候执行权限检测
*特俗情况等处理:在执行一些方法的时候,可能需要做某些特定的测试操作,而且经常改动,当时实际业务确
是固定的,这时候把特定操作当成一个切面,从而当需要修改的时候,也仅仅是只需要修改一
个地方而已,不是每个方法都去做改变
2、JDK的动态代理实现及原理(实际例子:操作日志记录)
2.1:正对一个业务类UserServiceImpl创建代理对象,并且生成操作日志
UserService 类如下:
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("add user");
}
public void delete() {
System.out.println("deleteuser");
}
public void update() {
System.out.println("update user");
}
public void find() {
System.out.println("find user");
}
}
public interface UserService {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
2.2、从上面可以看到要生成代理对象使用JDK自带的功能,必须实现接口,然而在spring这样的框架里面
可以发现,即时不实现接口也能生成代理对象,那样不实现接口生成代理对象的方式和JDK这样的生成
实现方式是不一样的,spring是借助了cglib去生成,jdk自带和cglib生成区别稍后在分析
2.3、JDK自带的实现方式,主要是利用java.lang.reflect.Proxy类
java.lang.reflect.InvocationHandler接口实现
2.3.1、Proxy类
构造方法一个
Proxy(InvocationHandler h):可见要创建Proxy类去创建代理对象,必须给Proxy传递实现InvocationHandler接口的类
方法
getInvocationHandler(Object proxy):返回某个代理类所关联的实现InvocationHandler类的对象
getProxyClass(ClassLoader loader, Class<?>... interfaces) :返回要代理类的class对象。
获取了代理对象的class实例,就可以获取代理对象的构造方法,new出一个实例,当然想通过这样的方式new,也是需要给他传递一个InvocationHandler接口的实现类的
isProxyClass(Class<?> cl):cl类是否是代理类,是返回true,不是返回false
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) :直接返回一个代理类的对象,通过上面方法getProxyClass能获取class
也可以生成代理对象,可见newProxyInstance只是getProxyClass的封装版,提供给我们一个更加容易操作的方法。
2.4、代理工厂,代理使用的地方可能有很多,这里把他封装起来,做成单例模式的实现
public class ProxyFactory implements InvocationHandler{
private static ProxyFactory proxyFactory;
private Object target;
private ProxyFactory() {};
public static ProxyFactory getInstance() {
if(proxyFactory == null) {
return new ProxyFactory();
}else {
return proxyFactory;
}
}
public Object getProxy(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//记录操作日志
System.out.println("执行方法:" + method.getName());
System.out.println("执行时间:" + new Date());
return method.invoke(target, args);
}
}
2.5、测试
public class Test {
public static void main(String[] args) {
UserService service = (UserService)ProxyFactory.getInstance().getProxy(new UserServiceImpl());
service.add();
System.out.println(Proxy.isProxyClass(service.getClass()));
}
}
打印结果:
执行时间:Fri May 13 11:50:55 CST 2011
add user
true
2.6、执行过程分析
首先执行Test类的main方法
ProxyFactory.getInstance()获取代理工厂ProxyFactory对象
getProxy():方法传递实际需要代理的对象过去,ProxyFactory保存实际代理对象用来后面实际调用
Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this)
生成代理对象,在调用的时候,代理对象调用方法的时候,它和实际对象拥有一样的方法和功能,当代理对象调用方法的时候,会去执行
invoke方法,执行完之后,Invoke方法同时也有真实调用的方法和参数,我们就利用代理保存的真实对象,去调用返回结果
3、JDK代理为什么一定得实现接口和原理
首先JDK里面实现是利用传入的接口去生成对应的代理类,所生成的代理类是和需要被代理的类实现的接口一样,从而他们也就
拥有相同的行为,如果传入的接口为空,直接是不进行生成代理对象的,装载器,生成的代理对象也是利用被代理类的装载器
去加载进来的。
在getProxyClass:首先会把所以传递过来的接口集合分析,加载,如果加载过程中出现错误,抛出错误,如果没有错误
把接口的名称组成集合,把接口的class保存起来,已经被生成的代理,会直接返回,没有被生成的就
先生成在缓存起来.
最后通过获取记载传入的接口获取其字节码文件,进行加载,生成出的代理类是如下结构
public class $Proxy extends Proxy implements 传入的接口
4、CGLIB是通过字节码的方式生成一个代理类的子类,所以在应用的时候
可以直接把代理类强制转化为具体的实现子类。而JDK动态代理则不可以,
他不是具体的子类,它只是实现接口的类,所以只能转化为指向父引用
的接口对象。
分享到:
相关推荐
Java动态代理是一种编程技术,主要用于在运行时创建一个新的对象,该对象可以作为现有接口的实现。动态代理的主要目的是为了在不修改原有代码的基础上,为已有的接口或类添加额外的功能,比如日志、事务管理、性能...
Java动态代理机制是Java语言提供的一种强大的功能,它允许在运行时创建代理对象来实现特定接口,从而可以灵活地扩展或增强已有代码的功能。在Java中,动态代理主要通过两个类来实现:`java.lang.reflect.Proxy` 和 `...
根据给定的信息,本文将重点解析Java动态代理技术,并适当关联Tomcat的配置与管理,因为给定部分内容涉及到了Tomcat的应用与管理。 ### Java动态代理技术解析 #### 一、Java动态代理简介 Java动态代理是Java反射...
### Java中的动态代理知识点解析 #### 一、动态代理概念 在Java中,动态代理是一种设计模式,它允许我们创建一个对象来代表另一个对象。这种模式通常用于在不修改目标对象的情况下,为对象添加额外的功能或者行为...
Java动态代理是一种强大的技术,它允许我们在运行时创建对象,这些对象可以作为其他对象的代理,从而在调用实际方法之前或之后执行额外的操作。在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang....
在Java中,基于动态代理和反射机制实现ORM可以提高代码的可维护性和灵活性。本篇文章将深入探讨如何在Java环境下,结合MySQL数据库,利用动态代理和反射技术来实现简单的ORM框架。 首先,我们需要了解动态代理和...
接下来,我们将通过给定的代码示例来详细解析Java动态代理的具体实现。 ##### 1. 接口定义 首先,我们定义了一个接口`MyInterface`,该接口包含两个方法:`print()`和`test(int num)`。 ```java public interface...
在Java开发过程中,动态代理技术是一项非常实用的技术,它可以帮助我们实现在不修改原有代码的基础上为方法增加额外的功能,比如日志记录、权限校验等。本文将深入分析JDK动态代理的工作原理及其内部实现机制。 ###...
Java动态代理机制是一种在运行时创建代理类和代理对象的技术,它允许我们在不修改源代码的情况下,对已有的接口或类进行扩展,增加新的功能。动态代理主要应用于事件监听、事务处理、性能监控等场景,提供了更加灵活...
Java反射是Java编程语言中的一个强大特性,...但需要注意的是,过度使用反射和动态代理可能会带来性能损失,因为它们都需要在运行时解析类信息,增加了额外的开销。因此,在实际开发中应适度使用,以平衡功能性和性能。
在Java中,代理模式有静态代理和动态代理两种实现方式。本篇将重点讨论"动态代理",这是一种在运行时创建代理对象的技术,使得我们可以在程序运行过程中,根据需要动态地生成具有额外功能的代理类。 动态代理主要由...
### JAVA类加载机制与动态代理 #### 一、类加载机制 ##### 1.1 类加载的时机 类加载机制负责将描述类的数据从`.class`文件加载到内存,并进行必要的校验、转换解析和初始化,使之成为可以被Java虚拟机直接使用的...
在Spring源码解析中,时序图用于描绘不同组件之间的调用关系,如AOP代理的生成过程、事件发布机制、数据访问层(DAO)与业务逻辑层(Service)的交互等。这有助于开发者理解Spring如何处理复杂的应用场景。 再者,...
Java反射和动态代理是Java编程中的重要特性,它们允许程序在运行时检查和操作类、接口、对象等的内部结构,以及动态地创建代理对象来处理特定任务。在这篇文章中,我们将深入探讨这两个主题,结合"reflections"这个...
Java平台标准版(J2SE)中的动态代理技术是自JDK 1.3版本引入的一个强大特性,它使得开发者可以在程序运行时动态地创建符合特定接口的代理对象。动态代理在实际应用中广泛用于实现面向切面编程(AOP),如日志记录、...
### Java静态代理与动态代理深度解析 #### 一、代理模式概述 代理模式是一种常见的设计模式,主要用于在访问目标对象之前或之后增加额外的操作。它通过代理类与委托类(真实对象)之间的交互,实现对目标对象功能...
总的来说,Java爬虫结合Jsoup实现动态IP代理是一个涉及网络通信、HTML解析、数据处理和代理机制等多个方面的综合性问题。理解并掌握这些知识点,不仅可以提升爬虫的实用性,还有助于提高对Web技术和网络编程的理解。