Java 动态代理

​代理模式是java常用的设计模式,他的特征是代理类和委托类有同样的接口,代理类主要负责为委托类预处理消息,过滤消息等操作。

根据代理的创建时期,可以分为静态代理和动态代理两种,本文主要针对动态代理进行说明。

 

1. 首先JDK为我们提供了一个类Proxy,通过该类,我们可以很方便的创建出代理类对象,首先我们来看下通过Proxy创建的代理类具有哪些构造方法以及对于参数类型,通过执行下面的代码我们可以看到返回的代理对应的构造方法以及参数类型

package com.jacksoft.proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.Collection;

/**
 *  动态代理
 *  通过对collection进行代理
 * @author Jack
 *
 */
public class ProxyTest {

	public static void main(String[] args) {
		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(),new Class[]{Collection.class});
		printConstructors(clazz);
	}
	
	/**
	 *  打印出构造方法以及对于参数类型
	 *  如:
	 *  add(java.lang.String)
	 * @param clazz
	 */
	private static void printConstructors(Class clazz){
		System.out.println("---------------------------构造方法--------------------------");
		Constructor[] constructors = clazz.getConstructors();
		StringBuilder sb = new StringBuilder();
		for(Constructor constructor : constructors){
			sb.append(constructor.getName());
			sb.append("(");
				Class[] parameterClass = constructor.getParameterTypes();
				if(parameterClass != null){
					for(Class c : parameterClass){
						sb.append(c.getName()).append(",");
					}
					if(parameterClass.length != 0){
						sb.deleteCharAt(sb.length()-1);
					}
				}
			sb.append(")");
		}
		System.out.println(sb.toString());
	}
}

 通过上面的代码,得到的结果如下:

---------------------------构造方法--------------------------
$Proxy0(java.lang.reflect.InvocationHandler)

 通过getProxyClass 这个方法返回的Class是$Proxy0,并不是我们传入的Collection,同时也只有一个带InvocationHandler参数的构造方法,所以接下来我们要对返回的Class通过反射来进行实例化操作,构造方法和对应参数都有了,很简单就能完成。由于InvocationHandler是接口,所以我们需要new一个实现出来传入。

	/**
	 *  返回实例对象
	 * @param clazz
	 * @return
	 * @throws  
	 * @throws SecurityException 
	 */
	private static Object getInstance(Class clazz) throws Exception{
		Constructor constructor = clazz.getConstructor(InvocationHandler.class);
		return constructor.newInstance(new InvocationHandler(){
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}
		});
	}

 

 这里主要来看下IncocationHandler中的invoke方法,该方法就是我们在调用目标方法时,执行的方法,有三个参数,分别对应如下:

Object proxy:代理的对象。 
Method method:要调用的方法 
Object[] args:方法调用时所需要的参数 

 当我们调用目标方法时,实际上是通过Method反射去调用,所以我们要添加的代码也就是需要在这里体现。

2. 接下来我们也通过简单的代码来实现advise功能,也就是常说的织入

一般advise有四种,分别是方法执行前,执行后,执行前后,异常中,这里我简单定义两种,执行前和执行后

为了标准规范,这里需要定义一个接口 

Advise:

package com.jacksoft.proxy;

/**
 *  Advise
 * @author Jack
 *
 */
public interface Advise {

	/**
	 * 方法执行前
	 */
	public void beforMethod();
	
	/**
	 * 方法执行后
	 */
	public void afterMethod();
}

 然后再写一个对应的实现类

MyAdvise:

package com.jacksoft.proxy;

public class MyAdvise implements Advise {

	@Override
	public void beforMethod() {
		System.out.println("-----------方法执行前-------------");
	}

	@Override
	public void afterMethod() {
		System.out.println("-----------方法执行后-------------");
	}

}

 这里只是简单的进行打印,可以根据实际的需求,还可以传入参数,比如对参数关键字进行替换之类的。

这里可以通过Proxy给我们提供的newProxyInstance方法来直接返回代理对象,写一个获取代理对象的工具类

ProxyUtils

package com.jacksoft.proxy;

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

/**
 * 代理工具类
 * @author Jack
 *
 */
public class ProxyUtils {

	public static Object getProxyInstance(final Object target,final Advise advise){
		
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				advise.beforMethod();
				Object reVal = method.invoke(target, args);
				advise.afterMethod();
				return reVal;
			}
		});
	}
}

 

这里在method.invoke前后都插入advise方法。

接下来再加上测试类,为了简单,这里我使用Colletion接口来生成代理对象

Client:

package com.jacksoft.proxy;

import java.util.ArrayList;
import java.util.Collection;

public class Client {

	public static void main(String[] args) {
		Advise advise = new MyAdvise();
		Collection coll = (Collection) ProxyUtils.getProxyInstance(new ArrayList(), advise);
		coll.add("1");
	}
}

 执行结果:

-----------方法执行前-------------
-----------方法执行后-------------

 这样就将我们的代码横切到目标代码中,从而不影响目标源代码的逻辑,也很容易进行卸载,方便管理

在信息技术快速发展的背景下,构建高效的数据处理与信息管理平台已成为提升企业运营效能的重要途径。本文系统阐述基于Pentaho Data Integration(简称Kettle)中Carte组件实现的任务管理架构,重点分析在系统构建过程中采用的信息化管理方法及其技术实现路径。 作为专业的ETL(数据抽取、转换与加载)工具,Kettle支持从多样化数据源获取信息,并完成数据清洗、格式转换及目标系统导入等操作。其内置的Carte模块以轻量级HTTP服务器形态运行,通过RESTful接口提供作业与转换任务的远程管控能力,特别适用于需要分布式任务调度与状态监控的大规模数据处理环境。 在人工智能应用场景中,项目实践常需处理海量数据以支撑模型训练与决策分析。本系统通过整合Carte服务功能,构建具备智能调度特性的任务管理机制,有效保障数据传递的准确性与时效性,并通过科学的并发控制策略优化系统资源利用,从而全面提升数据处理效能。 在系统架构设计层面,核心目标在于实现数据处理流程的高度自动化,最大限度减少人工干预,同时确保系统架构的弹性扩展与稳定运行。后端服务采用Java语言开发,充分利用其跨平台特性与丰富的类库资源构建稳健的服务逻辑;前端界面则运用HTML5、CSS3及JavaScript等现代Web技术,打造直观的任务监控与调度操作界面,显著提升管理效率。 关键技术要素包括: 1. Pentaho数据集成工具:提供可视化作业设计界面,支持多源数据接入与复杂数据处理流程 2. Carte服务架构:基于HTTP协议的轻量级服务组件,通过标准化接口实现远程任务管理 3. 系统设计原则:遵循模块化与分层架构理念,确保数据安全、运行效能与系统可维护性 4. Java技术体系:构建高可靠性后端服务的核心开发平台 5. 并发管理机制:通过优先级调度与资源分配算法实现任务执行秩序控制 6. 信息化管理策略:注重数据实时同步与系统协同运作,强化决策支持能力 7. 前端技术组合:运用现代Web标准创建交互式管理界面 8. 分布式部署方案:依托Carte服务实现多节点任务分发与状态监控 该管理系统的实施不仅需要熟练掌握Kettle工具链与Carte服务特性,更需统筹Java后端架构与Web前端技术,最终形成符合大数据时代企业需求的智能化信息管理解决方案。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值