Java reflection in NLP-four steps

Source: Internet
Author: User

Java reflection in NLP-four steps

 

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:

 

 

package com.tgb.state;/** *  * @author kang * */public interface Hello {public void say(String name);}


 

HelloImpl:

 

 

package com.tgb.state;public class HelloImpl implements Hello {@Overridepublic void say(String name) {System.out.println(this.getClass()+"  Hello!"+name);}}


 

 

The extracted General Code class ServiceBean:

 

Package com. tgb. dynamic. jdk; import java. lang. reflect. method; import java. util. hashMap;/*** service bean, which is a function to be reused in aop * @ author kang **/public class ServiceBean {// HashMap of the object before the proxy object method is put in place
 
  
BeforeBeans = new HashMap
  
   
(); // The HashMap object after the proxy object method is put
   
    
AfterBeans = new HashMap
    
     
(); // Specifies the HashMap method of the object before the proxy object method.
     
      
BeforeMethods = new HashMap
      
        (); // HashMap of the object method after the proxy object Method
       
         AfterMethods = new HashMap
        
          (); Public void before () throws Exception {for (HashMap. Entry
         
           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
          
            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
           
             GetBeforeBeans () {return beforeBeans;} public void setBeforeBeans (HashMap
            
              BeforeBeans) {this. beforeBeans = beforeBeans;} public HashMap
             
               GetAfterBeans () {return afterBeans;} public void setAfterBeans (HashMap
              
                AfterBeans) {this. afterBeans = afterBeans;} public HashMap
               
                 GetBeforeMethods () {return beforeMethods;} public void setBeforeMethods (HashMap
                
                  BeforeMethods) {this. beforeMethods = beforeMethods;} public HashMap
                 
                   GetAfterMethods () {return afterMethods;} public void setAfterMethods (HashMap
                  
                    AfterMethods) {this. afterMethods = afterMethods ;}}
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
 


 

Processing class MyInvokationHandler:

 

 

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 ;}}

Dynamically generate the proxy class MyProxyFactory for the proxy object:

 

 

 

Package com. tgb. dynamic. jdk; import java. lang. reflect. proxy; public class MyProxyFactory {/*** generate Proxy object * @ return */@ SuppressWarnings ("unchecked") public static
 
  
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 );}}
 

 

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:

 

 

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 ");}}

 

 

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

 

 

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
 
  
BeforeBeans = new HashMap
  
   
(); HashMap
   
    
AfterBeans = new HashMap
    
     
(); HashMap
     
      
BeforeMethods = new HashMap
      
        (); HashMap
       
         AfterMethods = new HashMap
        
          (); 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 ");}}
        
       
      
     
    
   
  
 

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.


Related Article

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.