`
gengu
  • 浏览: 85098 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

java 动态代理

    博客分类:
  • java
阅读更多

上一次说了java的代理模式。

其实java自己就提供了动态代理帮助我们实现代理模式,他的核心思想是在编写程序时不关心程序要代理谁,而是在运行的时候才关心我要代理谁。

 

java.lang.reflect.InvocationHandler是JDK提供的动态代理接口,对被代理类的方法进行代理。

invoke方法是接口InvocationHandler定义必须实现的,它完成对真实方法的调用。

 

动态代理是根据被代理的接口生成所有的方法,也就是先给定一个接口,动态代理会宣称“我已经实现该接口下的所有方法了”。通过InvocationHandler接口,所有方法都由该Hander来进行处理,即所有被代理的方法InvocationHandler接管实际的处理任务。

 

所以可以看到,被动态代理的类是必须要实现接口的,因为只有通过这个接口才能生成一个与被代理类配套的类。如果没有实现接口怎么办呢?Spring的做法是通过CGLIB来实现动态代理,也就是在加载字节码文件的时候来动态的产生代理类。

 

package com.gengu.代理.动态代理;
/** 抽象类*/
public interface Subject {
	public void doSomeThing();
	public void doanyThing();
}

 需要被代理的类

package com.gengu.代理.动态代理;

public class RealSubject implements Subject{
	@Override
	public void doSomeThing() {
		System.out.println("doSomeThing");
	}

	@Override
	public void doanyThing() {
		System.out.println("doAnyThing");
		
	}
}

 动态代理类,这里就显示的告诉程序代理到底该怎么做到,该增强什么功能,该监听什么之类的。

package com.gengu.代理.动态代理;

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

/**动态代理类*/
public class MyProxy implements InvocationHandler{
	//拦截类
	Intercept intercept=new Intercept();
	
	//代理者
	Object object = null;
	
	//需要代理谁
	public MyProxy(Object _obj){
		this.object = _obj;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] arg2)
			throws Throwable {
		
		intercept.Before();
		Object obj = method.invoke(this.object, arg2);
		intercept.After();
		return obj;
	}
}

 监听类或者切面类,面向切面编程的思想

package com.gengu.代理.动态代理;

public class Intercept {

	public void Before(){
		System.out.println("在调用方法之前");
	}
	
	public void After(){
		System.out.println("在调用方法之后");
	}
}

 测试类

package com.gengu.代理.动态代理;

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

/**
 * 测试类
 * */
public class Client {
	public static void main(String[] args) {
		//先得到需要被代理的类
		Subject subject = new RealSubject();
		//invocationHandler
		InvocationHandler invocationHandler = new MyProxy(subject);
		//类加载器
		ClassLoader classLoader = subject.getClass().getClassLoader();
		//动态产生一个代理者
		Subject subject2 = (Subject)Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, invocationHandler);
		subject2.doSomeThing();
	}	
}

 以上就是我对java动态代理的一点理解

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics