`

浅谈Java反射机制(二)

 
阅读更多
这一篇将会讲到利用java的反射机制而设计的动态代理模式。



•代理模式一般涉及到的角色有
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。


如果像上面描述那样,每个代理角色“都持有对真实对象的引用,并同时提供与真实对象相同的接口一遍在任何时刻代替真实对象”的话,那么我们可以很容易想象,随着需要代理的类增多,很快就会出现“类爆炸”的现象。

动态代理,是指在不知道真实角色的情况下,去调用正确的方法。

其实很简单,不要想得太复杂了,就是利用监听传进来的对象,在调用此方法时,在这方法之间做一个调用。

好啦,直接代码吧:

首先是抽象角色

[java] view plaincopyprint?package com.insigma.dymic; 
 
public interface Subject { 
    public void request(); 


package com.insigma.dymic;

public interface Subject {
public void request();
}

真实角色,就直接实现这接口就可以了

[java] view plaincopyprint?package com.insigma.dymic; 
 
public class RealSubject implements Subject{ 
 
    @Override 
    public void request() { 
        System.out.println("RealSubject do this"); 
    } 
 


package com.insigma.dymic;

public class RealSubject implements Subject{

@Override
public void request() {
System.out.println("RealSubject do this");
}

}

代理角色:



[java] view plaincopyprint?package com.insigma.dymic; 
 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
 
public class DynamicSubject implements InvocationHandler{ 
     
    private Object sub; 
     
    public DynamicSubject(){ 
         
    } 
     
    public DynamicSubject(Object object){ 
        sub = object; 
    } 
     
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable { 
        System.out.println("before calling " + method); 
        method.invoke(sub, args); 
        System.out.println("after calling " + method); 
         
        return null; 
    } 
     


package com.insigma.dymic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicSubject implements InvocationHandler{

private Object sub;

public DynamicSubject(){

}

public DynamicSubject(Object object){
sub = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling " + method);
method.invoke(sub, args);
System.out.println("after calling " + method);

return null;
}

}

使用代理角色的客户端:

[java] view plaincopyprint?package com.insigma.app; 
 
import java.lang.reflect.InvocationHandler; 
 
import com.insigma.dymic.DynamicSubject; 
import com.insigma.dymic.ProxyUtil; 
import com.insigma.dymic.RealSubject; 
import com.insigma.dymic.Subject; 
 
public class DynamicProxyApp { 
    public static void main(String[] args) { 
        Subject sub = new RealSubject(); 
        sub = (Subject) ProxyUtil.getInstance(sub); 
        sub.request(); 
    } 


package com.insigma.app;

import java.lang.reflect.InvocationHandler;

import com.insigma.dymic.DynamicSubject;
import com.insigma.dymic.ProxyUtil;
import com.insigma.dymic.RealSubject;
import com.insigma.dymic.Subject;

public class DynamicProxyApp {
public static void main(String[] args) {
Subject sub = new RealSubject();
sub = (Subject) ProxyUtil.getInstance(sub);
sub.request();
}
}


客户端的工具类:

[java] view plaincopyprint?package com.insigma.dymic; 
 
import java.lang.reflect.Constructor; 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Proxy; 
 
public class ProxyUtil { 
    public static Object getInstance(Object obj){ 
        InvocationHandler ds = new DynamicSubject(obj); 
        Class cls = obj.getClass(); 
         
        Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces()); 
        try { 
            Constructor cons = c.getConstructor(new Class[]{InvocationHandler.class}); 
            obj = cons.newInstance(new Object[]{ds}); 
        } catch (SecurityException e) { 
            e.printStackTrace(); 
        } catch (NoSuchMethodException e) { 
            e.printStackTrace(); 
        } catch (IllegalArgumentException e) { 
            e.printStackTrace(); 
        } catch (InstantiationException e) { 
            e.printStackTrace(); 
        } catch (IllegalAccessException e) { 
            e.printStackTrace(); 
        } catch (InvocationTargetException e) { 
            e.printStackTrace(); 
        } 
         
        return obj; 
         
    } 


package com.insigma.dymic;

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

public class ProxyUtil {
public static Object getInstance(Object obj){
InvocationHandler ds = new DynamicSubject(obj);
Class cls = obj.getClass();

Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces());
try {
Constructor cons = c.getConstructor(new Class[]{InvocationHandler.class});
obj = cons.newInstance(new Object[]{ds});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

return obj;

}
}



其实理清思路之后很简单,整一个测试的手敲代码连50行都没有。关键是要自己去想,自己想明白的才是你理解到的。

分享到:
评论

相关推荐

    Java反射技术浅谈.pdf

    Java反射技术浅谈 Java反射技术是一种强大的技术,它允许Java程序访问、检测和修改它自己的状态或行为。通过反射,Java程序可以加载一个运行时才知道名称的类,获取其完整的内部信息,并创建其对象,或者对其属性...

    Java反射技术浅谈 (1).pdf

    在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包。 * Class类:代表一个类。 * Field类:代表类的成员变量(成员变量也称为类的属性)。 * Method类:代表类的方法。 * Constructor类:...

    浅谈java反射和自定义注解的综合应用实例

    浅谈java反射和自定义注解的综合应用实例 Java 反射(Reflection)是 Java 语言中的一种机制,它允许程序在运行时检查和修改其结构和行为。Java 反射机制提供了一个实现运行时类型检查的机制,从而使得 Java 语言...

    浅谈Java程序设计在线开放课程.zip

    "浅谈Java程序设计在线开放课程"这个主题,将深入探讨Java语言的核心概念、编程实践以及如何通过在线平台有效地学习这门技术。 Java以其“一次编写,到处运行”的跨平台特性,成为了企业级应用开发的首选语言。课程...

    浅谈MyBatis通用Mapper实现原理

    浅谈MyBatis通用Mapper实现原理 MyBatis通用Mapper是MyBatis框架中的一种通用Mapper实现方式,主要提供了一些通用的方法,这些方法是以接口的形式提供的。通用Mapper的实现原理主要是通过Java反射机制和MyBatis框架...

    浅谈用java实现事件驱动机制

    总之,Java虽然没有内置的事件驱动机制,但通过观察者模式和反射机制,我们可以构建出符合需求的事件驱动系统。观察者模式更适用于通用和灵活的场景,而反射则适合对已知对象结构的简单事件处理。在实际开发中,应...

    浅谈Java中对类的主动引用和被动引用

    浅谈Java中对类的主动引用和被动引用 Java 中的类引用可以分为两种:主动引用和被动引用。理解这两种引用机制对于 Java 程序的正确执行和优化至关重要。 一、主动引用 主动引用是指在 Java 程序中明确地使用某个...

    浅谈Java中的class类

    在Java编程语言中,`Class`类扮演着至关重要的角色,它是Java反射机制的基础。`Class`类代表了运行时的类信息,允许我们在程序运行时动态地获取类的结构和属性,包括类的成员变量、方法、构造器等。这使得Java具备了...

    浅谈java Properties类的使用基础

    Java Properties类的使用基础 Java Properties类是Java标准库中的一种配置类,继承自HashTable,通常...Java Properties类是Java标准库中的一种配置类,提供了便捷的配置信息读写和持久化机制,广泛应用于实际项目中。

    浅谈Java编程中的内存泄露情况

    本文将深入探讨Java中的内存泄露及其相关的JVM垃圾回收机制。 首先,与C++等语言不同,Java引入了垃圾回收(Garbage Collection, GC)机制,自动负责管理内存,避免程序员手动释放内存可能导致的错误。然而,这并不...

    浅谈使用java实现阿里云消息队列简单封装

    浅谈使用java实现阿里云消息队列简单封装 本文主要介绍了使用Java实现阿里云消息队列的简单封装,包括对阿里云消息队列的介绍、设计方案、消息发送和接收的实现等。 一、阿里云消息队列简介 阿里云提供了两种消息...

    java基础PPT

    11. **JNI与JVM原理**:浅谈Java Native Interface(JNI),用于在Java程序中调用本地(非Java)代码,以及JVM的工作原理,包括类加载、内存管理和垃圾收集。 12. **案例分析**:可能包含一些简单的编程实例,帮助...

    java中Class.forName的作用浅谈

    1. **创建方式**:`newInstance()`是通过反射机制来创建对象,而`new`是直接创建。`newInstance()`要求类必须有一个无参构造器,而`new`可以调用任何公共构造器。 2. **灵活性与效率**:`newInstance()`提供了更大...

    浅谈计算机应用软件开发中编程语言的选择研究中英文对照.pdf

    浅谈计算机应用软件开发中编程语言的选择研究 随着信息技术的飞速发展,计算机应用软件已经深入到我们生活的各个领域,从个人娱乐、办公自动化到工业自动化、云计算等,无处不在。软件开发企业面临着激烈的市场竞争...

    浅谈对象与Map相互转化

    浅谈对象与Map相互转化 在 Java 开发中,对象与 Map 的相互转换是非常常见的需求。例如,在 Web 项目中,我们需要将 Java 对象转换为 JSON 数据,以便于前端 JavaScript 代码对其进行处理。又或者,在数据处理时,...

    java高手的文章合集1/3

    这个合集以“由一个简单的程序谈起”为主题,通过一系列文章深入浅出地介绍了Java语言的核心概念和技术。以下是这些文章可能涉及的重要知识点: 1. **Java入门**:文章可能从一个简单的“Hello, World!”程序开始,...

    浅谈Spring单例Bean与单例模式的区别

    "浅谈Spring单例Bean与单例模式的区别" 本文主要介绍了Spring单例Bean与单例模式的区别,通过对比两者的定义、实现机制和应用场景,帮助读者更好地理解这两种概念的异同。 一、单例模式的定义和实现 单例模式是一...

    浅谈SpringMVC中Interceptor和Filter区别

    浅谈SpringMVC中Interceptor和Filter区别 SpringMVC中Interceptor和Filter是两个重要的概念,它们都是用来处理用户请求的,但它们有着不同的作用和实现机制。本文将详细介绍Interceptor和Filter的区别,帮助读者更...

    浅谈Spring中@Import注解的作用和使用

    @Import 注解的实现原理是通过 Java 的反射机制来实现的。Spring 框架会在容器启动时扫描所有@Configuration 注解的配置类,并将其注册到容器中。然后,在容器中找到了@Configuration 注解的配置类后,Spring 框架会...

    asp.net知识库

    也谈 ASP.NET 1.1 中 QueryString 的安全获取写法 ASP.NET运行模式:PageHandlerFactory 利用搜索引擎引用来高亮页面关键字 网站首页的自动语言切换 应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动...

Global site tag (gtag.js) - Google Analytics