An example tutorial of Java implementing AOP for cutting-plane programming _java

Source: Internet
Author: User
Tags aop throwable

Introduced

As we all know, AOP (facet-oriented programming) is one of the features of the spring framework. AOP provides extremely high scalability by setting crosscutting concerns (cross cutting concerns). So how does AOP work in spring? When you can only use core Java, but you need AOP technology, the answer to this question becomes extremely critical. Not only that, but in interviews with senior technical posts, such problems often appear as questions. No, my friend had recently been interviewed and was asked the tricky question of how to implement AOP without using spring and related libraries, only with core Java. So I'm going to provide an outline in this article to help you understand how to implement only one AOP with Core Java (of course, this AOP has some limitations in functionality). Note that this article is not a comparative study of Spring AOP and Java AOP, but rather a tutorial on implementing AOP in core Java with inherent design patterns.

Presumably readers already know what AOP is and how to use it in the spring framework, so this article focuses on how to implement AOP without spring. First, we need to know that spring is the implementation of AOP using JDK Proxy and cglib two technologies. JDK Dynamic Proxy provides a flexible way to hook up a method and perform a specified operation, but there is a constraint when performing an operation: You must first provide an associated interface and an implementation class for that interface. Practice the truth, let us through a case to understand this sentence! Now there is a calculator program that completes some mathematical operations. Let's consider the next division feature, where the question is: if the core framework already has a code to implement division, can we hijack (highjack) it and perform additional validation while the code is executing? The answer is yes, I will use the code snippet provided below to prove this. First look at the code for the underlying interface:

Public interface Calculator {public
  int calculate (int a, int b);
}

The interface implements the code for the class as follows:

public class Calculatorimpl implements Calculator {
  @Override public
  int calculate (int a, int b) {return a/a
    ;
  }
}

If we can not repair the above code, and can not make any changes to the core library, how to achieve the perfect verification function? Let's try the JDK dynamic proxy function.

public class Somehandler implements Invocationhandler {
 
//Code omitted for simplicity
 
  ..... @Override Public
  Object Invoke (Object Proxy, Method method, object[] params) throws Throwable {
//Your complex Business validation and logic
    Object result = Method.invoke (targetobject, params);
    return result;
  }
 

Let's test the class to see how it works with the checksum implemented by JDK dynamic Proxy.

public static void Main (string[] args) {
    Calculatorimpl Calcimpl = new Calculatorimpl ();
    Calculator proxied = (Calculator) proxyfactory.getproxy (Calculator.class, Calcimpl, 
        new Somehandler (Calcimpl));
    int result = Proxied.calculate (a);
    System.out.println ("FInal Result:::" + result);
  }

From the result can be seen, simple to achieve a powerful Invocationhandler interface, we can get a hooking implementation. As described in the JDK documentation, the Invocationhandler interface handles a method invocation with the help of a proxy instance (proxy instance).

Now we know that Invocationhandler's Invoke () method can help us solve the problem. So, to solve a new problem-how do you do it before and after the method is executed? To be more specific, can we hook a method by adding multiple AOP (before, after, around) (add multiple aops, but I think handler is the role of aspect)? The answer is also yes. Follow these steps to create a streamlined code template that meets this need:

    • Create an abstract class to apply AOP to the target object.
    • Create two AOP named Beforehandler and Afterhandler. The former works before the method executes, and the latter works after the method execution ends.
    • Creates a proxy class that allows all AOP handler and target objects to be passed in as parameters, creating a hook.
    • Add your own business logic or crosscutting concerns.
    • Finally, the proxy object is created by passing in the relevant parameters.

Two ways to implement AOP:

Dynamic proxy implementation provided by 1,JDK
interface

Public interface UserBean 
{ 
  void GetUser (); 
  void AddUser (); 
  void UpdateUser (); 
  void DeleteUser (); 
} 

Original Implementation Class

public class Userbeanimpl implements UserBean 
{ 
  private String user = null; 
  Public Userbeanimpl () 
  {     
  } public   
  Userbeanimpl (String user) 
  { 
    this.user = user 
  }   
  Public String GetUserName () 
  {return 
    user; 
  }   
  public void GetUser () 
  { 
    System.out.println (' This is GetUser () method! '); 
  } 
 
  public void SetUser (String user) 
  { 
    this.user = user; 
    System.out.println ("This is SetUser () method!"); 
  } 
  public void AddUser () 
  { 
    System.out.println (' This is AddUser () method! '); 
  } 
   
  public void UpdateUser () 
  { 
    System.out.println (' This is UpdateUser () method! '); 
  }   
  public void DeleteUser () 
  { 
    System.out.println (' This is deleteuser () method! ');  
  }     
 

proxy class

Import Java.lang.reflect.InvocationHandler; 
Import Java.lang.reflect.Method; 
Import Java.lang.reflect.Proxy; 
Import Com.cignacmc.finance.bean.UserBeanImpl; 
 
public class Userbeanproxy implements Invocationhandler 
{ 
  private Object targetobject; 
   
  Public Userbeanproxy (Object targetobject) 
  { 
    this.targetobject = targetobject;     
  } 
   
  public object invoke (object proxy, Method method, object[] args) throws Throwable 
  { 
    Userbeanimpl = Rbeanimpl) TargetObject; 
    String userName = Userbean.getusername (); 
    Object result = null; 
     
    Permission to determine 
    if (userName!= null &&! "". Equals (UserName)) 
    {result 
      = Method.invoke (TargetObject, args); 
    } 
     
    return result; 
  } 
 


Test class

Import Java.lang.reflect.Proxy; 
Import Com.cignacmc.finance.bean.UserBean; 
Import Com.cignacmc.finance.bean.UserBeanImpl; 
 
Import Com.cignacmc.finance.proxy.UserBeanProxy; 
    public class Proxyexe {public static void main (string[] args) {System.out.println ("proved ... ...");    
    Userbeanimpl targetobject = new Userbeanimpl ("Bob Liang"); 
    Userbeanproxy proxy = new Userbeanproxy (targetobject); Build Agent Object UserBean object = (UserBean) proxy.newproxyinstance (Targetobject.getclass (). getClassLoader (), t 
    Argetobject.getclass (). Getinterfaces (), proxy); 
     
    Object.adduser (); 
    System.out.println ("NO proved ... ..."); ".    
    TargetObject = new Userbeanimpl (); 
    Proxy = new Userbeanproxy (targetobject); Build Agent object = (UserBean) proxy.newproxyinstance (Targetobject.getclass (). getClassLoader (), Targetobje 
    Ct.getclass (). Getinterfaces (), proxy); 
         
  Object.adduser (); 
 } 
}


Output:

 
proved ........ This is AddUser () method! 
NO proved ....... 


From the above example, we can successfully intercept the called Method AddUser () and handle it accordingly.

2, create proxy class through Cglib

The benefit is not to require our target object to implement the interface
Original class

public class Clientbean 
{ 
  private String name = NULL; 
 
  Public Clientbean () 
  { 
 
  } public 
 
  Clientbean (String name) 
  { 
    this.name = name; 
  } 
 
  public void Addclient () 
  { 
    System.out.println (' This is addclient () method! '); 
  } 
 
  public void Deleteclient () 
  { 
    System.out.println (' This is deleteclient () method! '); 
  } 
 
  public void Getclient () 
  { 
    System.out.println (' This is getclient () method! '); 
  } 
 
  public void Updateclient () 
  { 
    System.out.println (' This is updateclient () method! '); 
  } 
 
  Public String getclientname () 
  {return 
    name; 
  } 
 
  public void Setclientname (String name) 
  { 
    this.name = name; 
  } 
} 

proxy class

Import Java.lang.reflect.Method; 
 
Import Com.cignacmc.finance.bean.ClientBean; 
Import Net.sf.cglib.proxy.Enhancer; 
Import Net.sf.cglib.proxy.MethodInterceptor; 
 
Import Net.sf.cglib.proxy.MethodProxy; 
   
  public class Cglibproxy implements Methodinterceptor {private Object targetobject; 
    public Object Createproxyobject (object targetobject) {this.targetobject = TargetObject; 
    Enhancer enhancer = new enhancer (); 
    Enhancer.setsuperclass (This.targetObject.getClass ()); 
    Enhancer.setcallback (this); 
  return Enhancer.create (); 
  public object Intercept (object proxy, Method method, object[] args, Methodproxy methodproxy) throws Throwable 
    {Clientbean Clientbean = (Clientbean) targetobject; 
    String userName = Clientbean.getclientname (); 
     
    Object result = null; if (userName!= null &&! "". 
    Equals (UserName)) {result = Method.invoke (TargetObject, args); 
  return result; 
 } 
}

Test class

Import Java.lang.reflect.Proxy; 
 
Import Com.cignacmc.finance.bean.ClientBean; 
Import Com.cignacmc.finance.bean.UserBean; 
Import Com.cignacmc.finance.bean.UserBeanImpl; 
Import Com.cignacmc.finance.proxy.CGLibProxy; 
Import Com.cignacmc.finance.proxy.UserBeanProxy; 
 
public class Proxyexe 
{public 
  static void Main (string[] args) 
  {   
    System.out.println ("...). Cglib Proxy ... 
    ............ System.out.println ("proved .... ...)";; 
    ...... Cglibproxy cproxy = new Cglibproxy (); 
    Clientbean Clientbean = (Clientbean) cproxy.createproxyobject (New Clientbean ("Bob Liang")); 
    Clientbean.addclient (); 
     
    System.out.println ("NO proved ... ...) 
    ", and the "NO" is not. Cproxy = new Cglibproxy (); 
    Clientbean = (Clientbean) cproxy.createproxyobject (New Clientbean ()); 
    Clientbean.addclient (); 
         
  } 
 


Output:

............. Cglib Proxy ... 
.......... 
proved ............. This is addclient () method! 

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.