Java reflection-four steps and four steps of java

Source: Internet
Author: User

Java reflection-four steps and four steps of java


In the previous three articles, we will get the basic knowledge of reflection and the structure of the running class through reflection, such as, attributes, methods, parent classes, interfaces, annotations, and so on, this article describes how to call the specified attributes and methods of the running class through reflection. We will learn a typical running reflection, and the combination of dynamic proxy and AOP.

 

AOP Dynamic proxy

 

First, we will introduce a situation where code segments 1, 2, and 3 all contain the same code segment. Previous methods are completed by complex pasting of repeated code segments,


 

This situation described above must be improved. We can pull out the repeated code, let code segments 1, 2, and 3 call the extracted repeated code segments in the form of method calls. In this way, compared with the figure above, the code segments 1, 2, 3 and repeated are separated, but the code segments 1, 2, and 3 are coupled with the code that is extracted, for example:


 

The ideal result is that code segments 1, 2, and 3 can be called using method A, and the program does not need to call the method or hard code, the dynamic agent of AOP can solve this problem well.

 

For the implementation of dynamic AOP proxies, jdk reflection and CGLib are commonly used. The difference between them is that the former can not represent classes without interfaces, while CGlib can. We will not talk about the specifics, this article mainly aims to apply the reflection mentioned in the previous three articles. All our dynamic proxies are implemented using the reflection provided by jdk itself. Next we will use the dynamic proxy of jdk to solve this problem.

 

 

Implementation

 

 

 


 

 

First, the proxy interface Hello:

 

<span style="font-family:KaiTi_GB2312;">package com.tgb.state;/** *  * @author kang * */public interface Hello {public void say(String name);}</span>


HelloImpl:

 

<span style="font-family:KaiTi_GB2312;">package com.tgb.state;public class HelloImpl implements Hello {@Overridepublic void say(String name) {System.out.println(this.getClass()+"  Hello!"+name);}}</span>



The extracted General Code class ServiceBean:

<Span style = "font-family: KaiTi_GB2312;"> package com. tgb. dynamic. jdk; import java. lang. reflect. method; import java. util. hashMap;/*** service bean, is a function to be reused in aop * @ author kang **/public class ServiceBean {// HashMap of the object before the proxy object method is stored <String, object> beforeBeans = new HashMap <String, Object> (); // HashMap <String, Object> afterBeans = new HashMap <String, object> (); // HashMap <String, String> beforeMethods = new HashMap <String, String> (); // HashMap <String, String> afterMethods = new HashMap <String, String> (); public void before () throws Exception {for (HashMap. entry <String, Object> entry: beforeBeans. entrySet () {String beanKey = entry. getKey (); Object beforeBean = entry. getValue (); String beforeMethodValue = beforeMethods. get (beanKey); // System. out. println ("beforeMethodValue:" + beforeMethodValue); // Method beforeMethod = beforeBean to be executed using reflection. getClass (). getMethod (beforeMethodValue); // System. out. println ("beforeMethod:" + beforeMethod); // The method beforeMethod to be executed by the execution Class Using Reflection. invoke (beforeBean);} // System. out. println (this. getClass () + "Before");} public void after () throws Exception {for (HashMap. entry <String, Object> entry: afterBeans. entrySet () {String beanKey = entry. getKey (); Object afterBean = entry. getValue (); String afterMethodValue = afterMethods. get (beanKey); // System. out. println ("afterMethodValue:" + afterMethodValue); // obtain the Method to be executed for the Class Using Reflection Method afterMethod = afterBean. getClass (). getMethod (afterMethodValue); // System. out. println ("afterMethod:" + afterMethod); // The afterMethod to be executed by the running Class Using Reflection. invoke (afterBean);} // System. out. println (this. getClass () + "After");} public HashMap <String, Object> getBeforeBeans () {return beforeBeans;} public void setBeforeBeans (HashMap <String, Object> beforeBeans) {this. beforeBeans = beforeBeans;} public HashMap <String, Object> getAfterBeans () {return afterBeans;} public void setAfterBeans (HashMap <String, Object> afterBeans) {this. afterBeans = afterBeans;} public HashMap <String, String> getBeforeMethods () {return beforeMethods;} public void setBeforeMethods (HashMap <String, String> beforeMethods) {this. beforeMethods = beforeMethods;} public HashMap <String, String> getAfterMethods () {return afterMethods;} public void setAfterMethods (HashMap <String, String> afterMethods) {this. afterMethods = afterMethods ;}}</span>


Processing class MyInvokationHandler:


<Span style = "font-family: KaiTi_GB2312;"> package com. tgb. dynamic. jdk; import java. lang. reflect. invocationHandler; import java. lang. reflect. method; import java. lang. reflect. proxy;/*** processing class, used to load the reusable code class * @ author kang **/public class MyInvokationHandler implements InvocationHandler {private ServiceBean serviceBean; private Object target; public Object getTarget () {return target;} public void setTarget (Object target) implements this.tar get = target;} @ Overridepublic Object invoke (Object proxy, Method method, Object [] args) throws Throwable {serviceBean. before (); Object result = method. invoke (target, args); serviceBean. after (); return result;} public ServiceBean getServiceBean () {return serviceBean;} public void setServiceBean (ServiceBean serviceBean) {this. serviceBean = serviceBean; }}</span>

Dynamically generate the proxy class MyProxyFactory for the proxy object:


<Span style = "font-family: KaiTi_GB2312;"> package com. tgb. dynamic. jdk; import java. lang. reflect. proxy; public class MyProxyFactory {/*** generate Proxy Object * @ return */@ SuppressWarnings ("unchecked") public static <T> T getProxy (Object target, MyInvokationHandler handler) {// set the target object handler for MyInvokationHandler. setTarget (target); // create and return a dynamic Proxy object return (T) Proxy. newProxyInstance (target. getClass (). getClassLoader (), target. getClass (). getInterfaces (), handler) ;}</span>

 

By now, the overall class of aop dynamic proxy has been established. The careful colleagues found that the ServiceBean service class is a bit complicated because we abstract the service class here, so that the service class can also use reflection to dynamically load function classes that need to be reused. The reflection code in the class is what we learned in the first three articles.

 

Next let's take a look at the reusable function class HiImpl that needs to be dynamically loaded:


<Span style = "font-family: KaiTi_GB2312;"> package com. tgb. state; public class HiManage {public void hi () {System. out. println (this. getClass () + "Before method" + "hi method");} public void bye () {System. out. println (this. getClass () + "after method" + "bye method") ;}}</span>

 

Next let's take a look at our client code:


<Span style = "font-family: KaiTi_GB2312;"> package com. tgb. dynamic. jdk; import java. util. hashMap; import com.sun.org. apache. bcel. internal. generic. NEW; import com. tgb. state. hiManage; public class Client4 {public static void main (String [] args) {// --------------- load reusable function classes ------------------------ HashMap <String, Object> beforeBeans = new HashMap <String, object> (); HashMap <String, Object> afterBeans = new HashMap <String, Object> (); HashMap <String, String> beforeMethods = new HashMap <String, string> (); HashMap <String, String> afterMethods = new HashMap <String, String> (); beforeBeans. put ("HiManage", new HiImpl1 (); afterBeans. put ("HiManage", new HiImpl1 (); beforeMethods. put ("HiManage", "hi"); afterMethods. put ("HiManage", "bye"); ServiceBean serviceBean = new ServiceBean (); serviceBean. setBeforeBeans (beforeBeans); serviceBean. setAfterBeans (afterBeans); serviceBean. setBeforeMethods (beforeMethods); serviceBean. setAfterMethods (afterMethods); // ------------------ load reusable function classes; // set the reusable function classes after loading to MyInvokationHandler = new MyInvokationHandler () in the processing class (); handler. setServiceBean (serviceBean); // generate the proxy object Hello helloProxy = MyProxyFactory. getProxy (new HelloImpl (), handler); helloProxy. say ("zhangsan") ;}}</span>

Running result:


Class com. tgb. state. HiManage Before method hi Method

Class com. tgb. state. HelloImpl Hello! Zhangsan

Class com. tgb. state. HiManage's after method bye Method

 

 

Here, an aop dynamic proxy implemented using jdk reflection is completed. In 3, Hello and HelloImpl on the left are proxy classes, and ServiceBean on the far right is the abstract function class to be reused, we only abstract and encapsulate this abstract function class, and use reflection to allow this ServiceBean to dynamically load the specific function class to be reused, such as the HiManage class. Line 1 and line 2 both dynamically generate the Hello proxy class only when the client is called, and dynamically load the reusable feature class HiManage to jointly implement our dynamic AOP proxy.


 

Postscript

 

Through four articles in total, we learned the reflection knowledge through the specific demo code, including class Object creation and class object instance generation, and the specific structure of the class, such as constructor, attribute, method, annotation, parent class, and implementation interface. Finally, we introduce a typical application of aop dynamic proxy for reflection, we will introduce reflection first.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.