Spring Learning notes----AOP programming

Source: Internet
Author: User
Tags mul

Let's start with the code. What is traditional AOP (aspect-oriented programming) programming

Requirements: Implement a simple calculator to add logs before each step of the operation. The most traditional way is as follows:

Calculator.java

Package cn.limbo.spring.aop.calculator;/** * Created by Limbo on 16/7/14. */public interface Calculator {    int add (int i, int j);    int sub (int i, int j);    int mul (int i, int j);    int div (int i, int j);}
Calculatorimpl.java

Package cn.limbo.spring.aop.calculator;/** * Created by Limbo on 16/7/14. */public class Calculatorimpl implements Calculator {@Override public int add (int i, int j) {System.out.pri        Ntln ("The method add begin with [" + i + "," + j+ "]");        System.out.println ("The method add End with [" + i + "," + j+ "]");    return i + j; } @Override public int sub (int i, Int. j) {System.out.println ("the method sub begin with [" + i + "," + j+ "]"        );        System.out.println ("The method sub End with [" + i + "," + j+ "]");    return i-j; } @Override public int mul (int i, Int. j) {System.out.println ("The method mul begin with [" + i + "," + j+ "]"        );        System.out.println ("The method Mul end With [" + i + "," + j+ "]");    return I * j; } @Override public int div (int i, Int. j) {System.out.println ("the method div begin with [" + i + "," + j+ "]"        );        System.out.println ("The method div End With [" + i + "," + j+ "]");return i/j; }}
This completes the requirements, but we found that if you want to modify the log information, then you need to change in the specific method, this is cumbersome, and the original refreshing method is very confusing, the method should represent the core function, rather than these insignificant concerns, The following method is implemented in native Java to dynamically add output log methods when executing methods

Calculatorimpl.java

Package cn.limbo.spring.aop.calculator;/** * Created by Limbo on 16/7/14. */public class Calculatorimpl implements Calculator {    @Override public    int Add (int i, int j) {        return i + j;
   }    @Override public    int sub (int i, int j) {        return i-j;    }    @Override public    int mul (int i, int j) {        return i * j;    }    @Override Public    int div (int i, int j) {        return i/j;    }}

Calculatorloggingproxy.java

Package Cn.limbo.spring.aop.calculator;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.Method ; Import Java.lang.reflect.proxy;import java.util.arrays;import java.util.objects;/** * Created by Limbo on 16/7/14.    */public class Calculatorloggingproxy {//object to proxy private Calculator target;    Public Calculatorloggingproxy (Calculator target) {this.target = target; The public Calculator Getloggingproxy () {///proxy object is loaded by which class loader is responsible for loading ClassLoader loader = Target.getclass (). GetClass        Loader ();        The type of the proxy object, that is, which methods class[] interfaces = new Class[]{calculator.class};             When invoking a method in the proxy object, execute the code invocationhandler handler = new Invocationhandler () {@Override/**             * Proxy: The agent of the object that is being returned, in general, do not use the object in the Invoke method * Method: Methods being invoked * args: When calling a method, the passed in parameter */public object Invoke (object proxy, Method method, object[] args) throws Throwable {Stri Ng MethodName = Method.getname ();                System.out.println ("the method" + MethodName + "begins with" + arrays.aslist (args));                Log Object result = Method.invoke (Target,args);                System.out.println ("the method" + MethodName + "ends with" + result);            return result;        }        };        Calculator proxy = (Calculator) proxy.newproxyinstance (Loader,interfaces,handler);    return proxy; }}

Main.java

Package cn.limbo.spring.aop.calculator;/** * Created by Limbo on 16/7/14. */public class Main {public    static void Main (string[] args) {        Calculator Calculator = new Calculatorimpl ();        Calculator proxy = new Calculatorloggingproxy (Calculator). Getloggingproxy ();        int result = Proxy.add (up);        SYSTEM.OUT.PRINTLN ("--->" + result);        result = Proxy.sub;        SYSTEM.OUT.PRINTLN ("--->" + result);        result = Proxy.mul (3,2);        SYSTEM.OUT.PRINTLN ("--->" + result);        result = Proxy.div (14,2);        SYSTEM.OUT.PRINTLN ("--->" + result);}    }

This write although has simplified the code, and can arbitrarily modify the log information code, but it is still very troublesome to write!!!

Below we implement the spring-brought AOP package but join

Com.springsource.org.aopalliance-1.0.0.jar
Com.springsource.org.aspectj.weaver-1.8.5.release.jar

These two extra packages

Look at the code below, the main point of all the unload code inside

Calculator.java

Package cn.limbo.spring.aop.impl;/** * Created by Limbo on 16/7/14. */public interface Calculator {    int add (int i, int j);    int sub (int i, int j);    int mul (int i, int j);    int div (int i, int j);}
Calculatorimpl.java

Package Cn.limbo.spring.aop.impl;import org.springframework.stereotype.component;/** * Created is limbo on 16/7/14. */@Component ("Calculatorimpl") public class Calculatorimpl implements Calculator {    @Override public    int Add ( int i, int j) {        return i + J;    }    @Override Public    int sub (int i, int j) {        return i-j;    }    @Override public    int mul (int i, int j) {        return i * j;    }    @Override Public    int div (int i, int j) {        return i/j;    }}

Loggingaspect.java

Package Cn.limbo.spring.aop.impl;import Org.aspectj.lang.joinpoint;import Org.aspectj.lang.ProceedingJoinPoint; Import Org.aspectj.lang.annotation.*;import Org.springframework.core.annotation.order;import Org.springframework.stereotype.component;import Java.util.arrays;import Java.util.list;import java.util.Objects;/ * * Created by Limbo on 16/7/14. *///This class as a tangent: it is required to be placed in the IOC container, then declared as a slice @order (0)//Specify the tangent priority, the smaller the priority, the higher the @aspect@componentpublic class Loggingaspect {/** * A method that declares a pointcut expression, which, in general, does not need to add additional code in the method * primarily to re-use the path, using @pointcut to declare other notifications following the pointcut expression * to refer to the current pointcut expression directly using the method name */@Point    Cut ("Execution (* cn.limbo.spring.aop.impl.calculator.* (..))") public void Declarejointpointexpression () {}//declares that the method is a pre-notification: Executes the @Before before the target method ("Declarejointpointexpression ()"  )//@Before ("Execution (* cn.limbo.spring.aop.impl.*.* (..))") Any return value under the package, any class, any method, any parameter type public void Beforemethod (Joinpoint joinpoint) {String methodName = Joinpoint.getsig        Nature (). GetName (); List<object> args = Arrays.aslist (Joinpoint.getargs ());    System.out.println ("The Method" + methodname+ "begins with" + args); }//Executes after the target method executes, regardless of whether the method is faulted//The return value of the target method cannot be accessed in the post-notification, only access the @After by returning the notification ("Execution (* Cn.limbo.spring.aop.impl.Calculat Or.* (Int,int)) "public void Aftermethod (Joinpoint joinpoint) {String methodName = Joinpoint.getsignature ().        GetName ();    System.out.println ("The Method" + methodname+ "Ends"); /** * Code executed after the normal end of the method * Returns a notification that the return value of the method can be accessed */@AfterReturning (value = "Execution" (* cn.limbo.spring.aop.imp        L.calculator.* (..)) ", returning =" result ") public void afterreturning (Joinpoint joinpoint, Object result) {        String methodName = Joinpoint.getsignature (). GetName ();    System.out.println ("The Method" + MethodName + "Ends with" + result); /** * Execute code when the target method has an exception * you can access the exception object, and you can specify a specific exception when the notification is executed */@AfterThrowing (value = "Execution" (* CN.LIMBO.SPR Ing.aop.impl.calculator.* (..)) ", Throwing = "ex") public void afterthrowing (Joinpoint joinpoint,exception ex)//exception can be changed to a specific exception such as NullPointerException {        String methodName = Joinpoint.getsignature (). GetName ();    System.out.println ("The Method" + MethodName + "occurs with" + ex); /** * Surround notification requires Proceedingjoinpoint type parameters feature the most powerful * surround notification is similar to the whole process of dynamic agents: Parameters of the Proceedingjoinpoint type can determine whether to execute the target method * and the surround Pass    Must have a return value, which is the return value of the target method */@Around ("Execution (* cn.limbo.spring.aop.impl.calculator.* (..))")        Public Object Aroundmethod (Proceedingjoinpoint proceedingjoinpoint) {object result =null;        String methodName = Proceedingjoinpoint.getsignature (). GetName (); try {//Pre-Notification System.out.println ("the Method" + MethodName + "begins with" + arrays.aslist (Proceed            Ingjoinpoint.getargs ()));            result = Proceedingjoinpoint.proceed ();        Return notification System.out.println ("the Method" + MethodName + "Ends with" + result); } catch (Throwable throwable) {//Exception notification throwable.printstacktrace ();        } System.out.println ("The Method" + methodName + "Ends");    return result; }}


Applicationcontext.xml

<?xml Version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns:xsi= "http ://www.w3.org/2001/XMLSchema-instance "xmlns:context=" Http://www.springframework.org/schema/context "XMLNS:AOP = "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "Http://www.springframework.org/schema/beans Http://www.springframework.org/schema/beans/spring-beans.xsd Http://www.springframework.org/schema/context http ://www.springframework.org/schema/context/spring-context.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP/http Www.springframework.org/schema/aop/spring-aop.xsd "> <!--Configure auto-Scan Package--<context:component-scan Base-package= "Cn.limbo.spring.aop.impl" ></context:component-scan> <!--make aspect annotations work and automatically generate proxy objects for matching classes- > <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans> 

Using XML to configure AOP

Application-config.xml

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:tx= " Http://www.springframework.org/schema/tx "xsi:schemalocation=" Http://www.springframework.org/schema/beans http:/ /www.springframework.org/schema/beans/spring-beans-2.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www. Springframework.org/schema/aop/spring-aop-2.0.xsd Http://www.springframework.org/schema/tx Http://www.springfram Ework.org/schema/tx/spring-tx-2.0.xsd "> <bean id=" Usermanager "class=" Com.tgb.aop.UserManagerImpl "/>& lt;! --<bean id= "Aspcejhandler" class= "Com.tgb.aop.AspceJAdvice"/>--><bean id= "Xmlhandler" class= " Com.tgb.aop.XMLAdvice "/><aop:config><aop:aspect id=" aspect "ref=" Xmlhandler "><aop:pointcut id=" Pointusermgr "expression=" Execution (* com.tgb.aop.*.find* (..))" /><aop:before method= "Dobefore" pointcut-ref= "pointusermgr"/><aop:after method= "DoAfter" pointcut-ref= "Pointusermgr"/><aop:around method= "Doaround" pointcut-ref= "Pointusermgr"/><aop:after-returning Method= "Doreturn" pointcut-ref= "pointusermgr"/><aop:after-throwing method= "dothrowing" throwing= "ex" pointcut-ref= "Pointusermgr"/></aop:aspect></aop:config></beans>


A total of 5 types of notifications, of which around is the most powerful, but not necessarily the most commonly used, aspect the bottom of the implementation are through the agent to achieve, can only say this wheel made good







Spring Learning notes----AOP programming

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.