Spring--The basics of getting started with AOP

Source: Internet
Author: User
Tags mul

Dynamic Agent

Do we encounter this situation in our daily development process?

The red box is the log we want to output, do you find that most of the information in the log is the same, and if we want to modify a place, all the places need to change, and the code seems to be more redundant

Below we can solve this problem by dynamic agent method
Look at the code.

publicinterface Calculation {    publicintadd(intint y);    publicintsub(intint y);    publicintmul(intint y);    publicintdev(intint y);}

Define interfaces, subtraction methods.

 Public  class Calculationimpl implements calculation {    @Override     Public int Add(intXintY) {intresult = x + y;returnResult }@Override     Public int Sub(intXintY) {intresult = x-y;returnResult }@Override     Public int Mul(intXintY) {intresult = x * y;returnResult }@Override     Public int Dev(intXintY) {intresult = x/y;returnResult }}

The concrete implementation class, here we see, no implant logs.

 Public classCalculationproxy {PrivateCalculation calculation =NULL; Calculationproxy (calculation calculation) { This. calculation = calculation; } PublicCalculationGetcalculationlog() {Calculation proxy =NULL;        ClassLoader loader = Calculation.getclass (). getClassLoader (); Class[] Interfaces =NewClass[] {calculation.class}; Invocationhandler h =NewInvocationhandler () {@Override PublicObjectInvoke(Object proxy, method, object[] args) throws Throwable {System. out. println ("Gp-->invoke begin, Execute method is"+ method.getname () +", args is"+ arrays.aslist (args)); Object obj = method.invoke (calculation, args);returnObj        }        }; Proxy = (calculation) proxy.newproxyinstance (loader, interfaces, h);returnProxy }}

The implementation of the dynamic proxy class, when implementing the Invoke method, we output the log before calling the target method.

Test

publicclass Main {    publicstaticvoidmain(String[] args) {        new CalculationImpl();        new CalculationProxy(calculation);        Calculation cal = calculationProxy.getCalculationLog();        System.out.println(cal.add(13));        System.out.println(cal.mul(15));    }}

Output results

Gp–>invoke begin, Execute method is add, args is [1, 3]
4
Gp–>invoke begin, Execute method is Mul, args is [1, 5]
5

It seems to be more clear, we separate the log into the dynamic agent method, the core business methods are not intrusive, but also facilitate our maintenance.

Introduction to AOP

AOP (aspect-oriented programming, facet-oriented programming): A new methodology that complements traditional OOP (object-oriented programming, object-oriented programming).
The main programming objects of AOP are facets (aspect), while facets are modular crosscutting concerns.
When you apply AOP programming, you still need to define public functionality, but you can clearly define where and how this function is applied, without having to modify the affected classes. This way the crosscutting concerns are modularized into special objects (facets).
Benefits of AOP:

    • Each thing logic is in one place, code is not scattered, easy to maintain and upgrade
    • The business module is more concise and contains only the core business code.
AOP terminology

Facets (Aspect): Special objects that are modularized by crosscutting concerns (functions that span multiple modules of the application)
Notification (Advice): The work that the slice must complete
Target: The object being notified
Proxy: An object created after the notification is applied to the target object
Connection point (Joinpoint): A specific location for a program to execute, such as before a method call to a class, after a call, after a method throws an exception, and so on. The connection point is determined by two information: The program execution point represented by the method, and the orientation represented by the relative point. For example, the connection point before the Arithmethiccalculator#add () method executes, the execution point is Arithmethiccalculator#add (), and the position is before the method executes.
Tangency Point (pointcut): Each class has multiple connection points: for example, all methods of arithmethiccalculator are actually connection points, that is, the connection point is an objective transaction in the program class. AOP navigates to a specific connection point through a pointcut. Analogy: A connection point is equivalent to a record in a database, and a tangent is equivalent to a query condition. Tangency and connection points are not a one-to-one relationship, a pointcut matches multiple connection points, and the pointcut is described by the Org.springframework.aop.Pointcut interface, which uses classes and methods as query criteria for connection points.

aop– pre-notification based on aspect

For more information, refer to: http://jinnianshilongnian.iteye.com/blog/1420689

involving JAR packages
Com.springsource.net.sf.cglib-2.2.0.jar
Com.springsource.org.aopalliance-1.0.0.jar
Com.springsource.org.aspectj.weaver-1.6.8.release.jar
Commons-logging-1.1.1.jar
Spring-aop-4.1.7.release.jar
Spring-aspects-4.1.7.release.jar
Spring-beans-4.1.7.release.jar
Spring-context-4.1.7.release.jar
Spring-core-4.1.7.release.jar
Spring-expression-4.1.7.release.jar

Look at the code.

public   Interface  Calculation {public  int  add  (int  x, int  y); public  int  sub     (int  x, int  y); public  int  mul     (int  x, int  y); public  int  dev  (int  x, int  y);}  
@Component Public  class Calculationimpl implements calculation {    @Override     Public int Add(intXintY) {intresult = x + y;returnResult }@Override     Public int Sub(intXintY) {intresult = x-y;returnResult }@Override     Public int Mul(intXintY) {intresult = x * y;returnResult }@Override     Public int Dev(intXintY) {intresult = x/y;returnResult }}

Implement the interface, and use @component to mark the components in the IOC container.

    <context:component-scan base-package="com.gp.spring.aop.impl"></context:component-scan>    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

Adds a package path for scanning annotations.
Spring does not support @aspectj-style facet declarations by default, adding Aspectj-autoproxy so that spring can discover @aspectj-style facets and apply facets to the target object.

 @Aspect   @Component  public  class  calculationaspect  {  @Before  ( "execution (public int com.gp.spring.aop.impl.Calculation.add (int, int))" ) public  void  beforemethod         (Joinpoint joinpoint) {String name = Joinpoint.getsignature (). GetName ();        list<object> list = Arrays.aslist (Joinpoint.getargs ()); System.out.println ( "Method begin ..., method="  + name + 
    • Calculationaspect marked as component component, registered in IOC container
    • @Aspect tag, spring configures its AOP-related configuration to generate the corresponding proxy class
    • @Before, notification before the method execution for the pre-notification
    • "Execution (public int com.gp.spring.aop.impl.Calculation.add (int,
      int)) "expression that represents information about the package path, method, to be performed by this notification. This expression can be fuzzy-matched, such as "Execution (public int
      com.gp.spring.aop.impl.calculation.* (*)) ", which represents all methods under the calculation class.
    • The parameter in the Joinpoint method is Joinpoint, which represents the connection point, which allows you to obtain information about the execution method, such as the method name, method parameters.

Executing test methods

    publicstaticvoidmain(String[] args) {        new ClassPathXmlApplicationContext("applicationContext.xml");        Calculation calculation = (Calculation)context.getBean("calculationImpl");        int result = calculation.add(34);        System.out.println(result);    }

Output results

Method begin ..., method=add, args = [3, 4]
7

aop– post notification based on aspect

The post notification is similar to the predecessor notification usage, except that the post-notification method is executed after the method is executed.

The code is as follows

    @After("execution(public int com.gp.spring.aop.impl.Calculation.add(int, int))")    public void afterMethod(JoinPoint joinPoint) {        String name = joinPoint.getSignature().getName();        List<Object> list = Arrays.asList(joinPoint.getArgs());        System.out.println("Method end ... ,method="", args = "                + list);    }

The @after annotations are used here, and nothing else has changed.

The results of the test output are as follows

Method begin ..., method=add, args = [3, 4]
Executeing ...
Method end ..., method=add, args = [3, 4]
7

I've added an output to the Add method to make it easier to differentiate between pre-and post-notification

    publicintadd(intint y) {        int result = x + y;        System.out.println("executeing ...");        return result;    }
aop– return notification based on aspect

When the method executes successfully, the call returns a notification that is not invoked if the method throws an exception during the run.

Code

@AfterReturning (value ="Execution (public int com.gp.spring.aop.impl.Calculation.add (int, int))", returning ="ret") public void Afterreturnmethod (Joinpoint joinpoint, Objectret) {String name = Joinpoint. Getsignature(). GetName();list<object> list = Arrays. Aslist(Joinpoint. Getargs());System. out. println("@AfterReturning ..., method=."+ name +", args ="+ list +", return ="+ret);}

Unlike post-notification, a post-notification is thrown in the method, and is still called, where we can use the Try ... catch ... The analogy.

Output results

@Before ..., method=add, args = [3, 4]
Executeing ...
@After ..., method=add, args = [3, 4]
@AfterReturning ..., method=add, args = [1, 3], return = 4
7

aop– exception notification based on aspect

method calls exception notification if an exception is thrown during the run

Code

    @AfterThrowing(value"execution(public int com.gp.spring.aop.impl.Calculation.*(int, int))""ex")    publicvoidafterThrowMethod(JoinPoint joinPoint, Exception ex) {        System.out.println("@AfterThrowing ... ,ex = " + ex);    }

Here with the previous usage some but do not, add throwing in the parameters of the annotations, and then add the exception to be caught in the method, similar to Try...catch ... Block of code in catch

Output results

Exception in thread "main" @AfterThrowing ..., ex = java.lang.ArithmeticException:/by zero
Java.lang.ArithmeticException:/By zero
At Com.gp.spring.aop.impl.CalculationImpl.dev (calculationimpl.java:29)

Aspect-based aop– surround notification

Surround notifications, similar to the dynamic agents we started with, in this notification you can call the target method and make various notifications (front, back, back, exception, etc.) on the target method.

Code:

@Around ("Execution (public int com.gp.spring.aop.impl.Calculation.add (int, int))"Public Object Aroundmethod (Proceedingjoinpoint pjd) {String name = PJD. Getsignature(). GetName();list<object> list = Arrays. Aslist(PJD. Getargs());Object obj = null;System. out. println("Pre-notification ..., method="+ name +", args ="+ list);try {obj = Pjd. Proceed();System. out. println("return notification ..., method="+ name +", args ="+ list);} catch (Throwable e) {System. out. println("Exception notification ..., exception ="+ e);E. Printstacktrace();} System. out. println("post-notification ..., method="+ name +", args ="+ list);return obj;}

return Result:

Pre-notification ..., method=add, args = [1, 3]
Executeing ...
Return notification ..., method=add, args = [1, 3]
Post notification ..., method=add, args = [1, 3]
4

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Spring--The basics of getting started with AOP

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.