Java-oriented AOP programming

Source: Internet
Author: User

First, Introduction

AOP (aspect-oriented programming, aspect-oriented programming) is a new type of programming paradigm that advocates focusing on one aspect of the software process, bundling the same functional code together, reducing the coupling of the system and enhancing its extensibility.

Traditional software design often takes an event-driven model to bring about similar effects by inserting an event callback function at a possible event pointcut and inserting the corresponding location into the external code.

Functional programming, there are similar solutions, through function passing, will correspond to the location of the extension on the new function.

Java as a rigorous traditional development language, with security and reliability as the first standard, the language does not have too many new features support, JAVA8 only support to lambda expression, in order to make Java a more powerful programming model, Frameworks such as spring use the Gclib library to implement a tangent-oriented programming model.

Ii. CGLIB and ASM

CGLIB is a powerful, high-performance, high-quality code generation library that is widely used as a dynamic agent technology. The bottom of the CGLIB package is to convert bytecode and generate new classes by using a small and fast bytecode processing framework ASM, and the new bytecode can be loaded and run directly by the Java Virtual machine.

In fact, dynamic agent is not cglib patent, as early as the JDK1.3 version, introduced the dynamic Agent library, Spring AOP programming can be selected, using the dynamic Agent library provided by the JDK, or the introduction of Cglib library.

Here is an example of how to use the Cglib library to truncate a function call that we should normally execute.

package com.abs.testcglib;publicclass Service {    String name;    publicService(String name) {        this.name = name;    }    publicvoidsayHello() {        System.out.println("Hello "+name);    }}

First, we create a service class that has a sayHello() method that we want to truncate to add some processing functionality for the rest of the components, such as a feature that the persistence component wants to add a record to.

package com.abs.testcglib;publicclass Main {    publicstaticvoidmain(String[] args) {        new Service("Sxf");        s.sayHello();    }}

In the main function call, you can see the Hello Sxf output.

But how do we truncate it? The first is to create a proxy class, the so-called proxy, you let this proxy class, for you to call the function of this class.

Create a proxy class:

 PackageCom.abs.testcglib;ImportNet.sf.cglib.proxy.MethodInterceptor;ImportNet.sf.cglib.proxy.MethodProxy;ImportJava.lang.reflect.Method; Public  class cglibproxy implements methodinterceptor {    @Override     PublicObjectIntercept(Object o, method, object[] args, Methodproxy methodproxy)throwsThrowable {System.out.println ("Method Name:"+method.getname ());        Service A = (service) O; A.name ="Wah"; System.out.println ("Haha, I want to change my name."); Object result = Methodproxy.invokesuper (o, args);returnResult }}

The function of this proxy class is to make the traditional Java direct function call, package on the shell, because the function call of Java itself is the system, it is difficult for you to big paragraph him, but the proxy class is different, you can clearly see the call of which function, and can be based on this, easily before and after the function call, Insert the code that you want to insert.

public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy)
This function is probably the most critical function in the entire proxy invocation, and O This parameter represents the object that the function is in, and args is the calling parameter, and method is the one that is reflected. The last one is an instance of the proxy.
The interrupt function of our function is implemented in this function.

Of course, because of the implementation of the proxy, the construction of the object is also different, so we write a static function as a constructor to use.

Package Com.abs.testcglib;import Net.sf.cglib.proxy.Enhancer; Public classService {String name; Public Service(String name) { This. name = name; } Public void SayHello() {System. out. println ("Hello"+name); } Public StaticServicegetproxyinstance(Cglibproxy myproxy, String name) {Enhancer en =NewEnhancer ();//Set parent class and callbackEn.setsuperclass (Service.class); En.setcallback (myproxy);//Call its constructor, need to pass in the corresponding class list and Parameter object list        return(Service) En.create (NewClass[] {String.class},NewObject[] {name}); }}

This object should be used in the main function as well:

package com.abs.testcglib;publicclass Main {    publicstaticvoidmain(String[] args) {        new Service("Sxf");        s.sayHello();        Service s2 = Service.getProxyInstance(new"Sxf");        s2.sayHello();    }}

We found that two ways to create the object, using almost the same, the only difference is the constructor, we made a partial modification, the rest, does not affect the normal delivery of our objects, storage and other functions.

Final effect:

Third, the implementation of Spring AOP

In fact, it seems that the implementation of the Cglib, and then look at the famous spring framework, will find that the two implementations are almost identical, except that the spring framework adds a number of concepts and functions.

Below we write a target class, which is an object that is being proxied, and there is a execute() method that now uses AOP to do the log output of the execute() method. Do the execute() log output before executing the method.

publicclass Target {    publicvoidexecute(String name){        System.out.println("executeMethod is here" + name);    }}

Notifications can intercept the Execute () method of the target object and execute the log output. The code to create the notification is as follows:

publicclass LoggerExecute implements MethodInterceptor {    publicinvokethrows Throwable {        before();        arg0.proceed();        returnnull;    }    privatevoidbefore() {        System.out.println("executeMethod is exe!");    }}

The methods for creating proxies are almost the same:

publicstaticvoidmain(String[] args) {    //创建目标对象    new Target();    //创建代理    ProxyFactory di=new ProxyFactory();    di.addAdvice(new BeforeExecute());    di.setTarget(target);    Target proxy=(Target)di.getProxy();    //代理执行execute()方法    proxy.execute(" ni hao");}

Of course, Spring's pointcut is closely associated with its configuration file, with the spring framework being able to throw more fixed parameters of the system into the configuration file, or use annotations directly.

Java-oriented AOP programming

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.