Dynamic agent understanding

Without further ado, go directly to the code!
Note! We need an interface and the implementation class of the interface!

 public static void main(String[] args) {
		
	//1param: 固定值: 告诉虚拟机用哪个字节码加载器加载内存中创建出的字节码文件
	//2param: 告诉虚拟机内存中正在被创建的字节码文件中应该有哪些方法
	//3param: 告诉虚拟机正在被创建的字节码上的各个方法如何处理, InvocationHandler  h:得到InvocationHandler接口的子类实例


	ICar(接口) car=(ICar)Proxy.newProxyInstance(TestCar.class.getClassLoader(), GoogleCar.class.getInterfaces(),new InvocationHandler() {
		
		//method:代表正在执行的方法
		//args:代表正在执行的方法中的参数
		//Object:代表方法执行完毕之后的返回值
		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			//经过测试得知:method代表当前正在执行的每个方法
			//System.out.println(method.getName());
			//执行当前的方法
			//method.invoke(new GoogleCar(), args);
			
			
			//代表每个方法执行完毕之后返回对象
			Object obj=null;
			
			if(method.getName().equalsIgnoreCase("start")){
				System.out.println("检查天气是否良好");

				//打印args中的内容
				System.out.println(Arrays.toString(args));
				
				obj=method.invoke(new GoogleCar(), args);
				System.out.println("检查路况是否拥堵");
				
			}else{
				obj=method.invoke(new GoogleCar(), args);	
			}
			return obj;
		}
	});
	
	String cc=car.start(1,4);
	System.out.println(cc);
	car.run();
	car.stop();
	
}

1. What is ClassLoader?
Everyone knows that when we write a Java program, whether it is a CS or BS application, it is a complete Java application organized by several .class files. When the program is running At that time, an entry function of the program will be called to call related functions of the system, and these functions are encapsulated in different class files, so it is often necessary to call methods in another class file from this class file. If another file does not exist, it will cause a system exception. When the program starts, it does not load all the class files used by the program at once, but dynamically loads a class file into memory through the Java class loading mechanism (ClassLoader) according to the needs of the program. Only after the class file is loaded into memory can it be referenced by other classes. So ClassLoader is used to dynamically load class files into memory.

	//获取String类的加载器
	ClassLoader classLoader = String.class.getClassLoader();
	System.out.println(classLoader);
	//由于String.class ,int.class等字节码文件需要频繁的被加载内存,速度必须快,底层用其他语言来实现c c++
	
	//获取ext(extendtion)包下的某个类的字节码加载器   ExtClassLoader:扩展类加载器
	ClassLoader classLoader2 = sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader();
	System.out.println(classLoader2);

	//应用类:程序员实现的所有的类都属于应用类
	//获取应用类加载器 AppClassLoader
	ClassLoader classLoader3 = TestClassLoader.class.getClassLoader();
	System.out.println(classLoader3);
}

}
Insert picture description here

// Get all the interfaces on the Google Car googleCar.class bytecode file. Googlecar may implement multiple interfaces
Class [] clazz = GoogleCar.class.getInterfaces ();

	//由于当前案例中谷歌Car仅实现了一个接口ICar
	//以下代码相当于获取到了ICar.class字节码对象
	Class cla=clazz[0];
	//获取ICar.class字节码对象上所有的方法
	Method[] mds = cla.getMethods();
	for (Method method : mds) {
		System.out.println(method.getName());

The methods of the original class cannot be decorated!
Example: Using Filter to deal with garbled characters

		public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				//将request对象转换为HttpServletRequest
				final HttpServletRequest req=(HttpServletRequest)request;
				//让JDK在内存中生成代理对象:增强了req对象上的getParameter(name);API
				HttpServletRequest myReq=(HttpServletRequest)Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
<? req.getClass (). getInterfaces () tells what methods should be in this proxy class?> <? How to know that there must be getparamter in this method? The following Method is not an array> <? In the browser to After the server sends the request, the server receives the request. Before calling the service method to process the request, it will create a Request object and encapsulate all the request information (request line, request header, request entity) into the Request object?> <? / / After testing, I know: method represents each method currently being executed?> <? How do I know that request is currently executing getParameter?> <? This is a rewritten method to be enhanced?> <? Method is a method object obj Is the class object instance where the method object is located args is a method parameter?>

Insert picture description here

@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				<?这个method是方法调用时才走invoke()?这一段重载方法在未调用之前都可以不看>
				Object obj=null;
				
				if(method.getName().equalsIgnoreCase("getParameter")){
					//获取本次请求方式
					String md=req.getMethod();
					if("get".equalsIgnoreCase(md)){
<? The transmission method was originally specified on the jsp page?>
					//get方式的请求
					//调用req对象上的getParameter方法
					String v=(String)method.invoke(req, args);
					//转码
					String vv=new String(v.getBytes("iso-8859-1"),"utf-8");
					return vv;
<? Where to return?> <? Return to the transcoded recipient, the part after return is not necessary to read?>
				}else{
					//post方式的请求
					req.setCharacterEncoding("utf-8");
					obj=method.invoke(req, args);<?调用getparamters?>
				}
				
				
			}else{
				obj=method.invoke(req, args);
			}
			return obj;
		}
	});
	//打印代理对象哈希码
	System.out.println(myReq.hashCode());
	//将代理对象放行
	chain.doFilter(myReq, response);
<? Return the packaged myreq to the server?>
}

Difficulty: understand the meaning of each parameter and don't forget whether you need to return the encapsulated class, or pay attention to the return type of the original function, this part corresponds to the return of the obj parameter. (For novices, I have always found it incomprehensible How to achieve the bottom layer, when learning a certain knowledge point, just remember its steps and the meaning of the class or interface method used. Later I want to open it, is it not to learn according to the gourd painting scoop? Difficult! I will definitely learn the underlying principles!)
I have been entangled in the sequential execution thinking of the program, so I have not been out of that circle, where is it around. In fact, just write the Proxy.newProxyInstance that needs to be enhanced , You do n’t need to worry about it. Because when calling a function in an interface you need, the invoke method will give you a judgment as to whether it is the function you need to enhance! Of course, you must write in advance for this part good!
dynamic proxy has the advantage that make up the interface class decorator pattern in many ways when the wrapper class need to override a lot of functions.
dynamic proxy need only when you need that interface When a function to invoke methods walked about, determine what you call a function of the moment is not the function you need, and then to add the content you want on the basis of the original method on!
All in all!
Proxy and the overriding invoke methods from the A process of screening and using methods in the interface!
Where is the dynamic manifestation?
Load (copy) the functions you need from the implementation class of the interface through the class loader and add the functions you need to the packaging class! It is a dynamic process, you need to load it, the judgment method is the method you need to load it. The
loading process is implemented in the jvm, usually in order to load the speed, generally use c / c ++ to write this part of the code! The
above are all Personally understand, there are inevitable mistakes, after all, I just just entered the door of java.
Work hard together!
Hee hee, self-discipline!

Published 37 original articles · won praise 6 · views 4669

Guess you like

Origin blog.csdn.net/littlewhitevg/article/details/89294621