Annotation-based spring AOP configuration and usage

Source: Internet
Author: User
Tags getmessage

AOP (plane-oriented programming)

In the software industry, AOP is the abbreviation for Aspect oriented programming, which means: face-cutting programming, through the pre-compilation method and runtime dynamic agent to implement the unified maintenance of the program functions of a technology. AOP is a continuation of OOP, a hotspot in software development, an important content in the spring framework, and a derivative model of functional programming. AOP enables the isolation of parts of the business logic, which reduces the coupling between parts of the business logic, improves the reusability of the program, and improves the efficiency of development.

Main functions of logging, performance statistics, security control, transaction processing, exception handling and so on. The main intent is to divide the code of logging, performance statistics, security control, transaction processing, exception handling, and so forth from the business logic code, and by separating these behaviors, we want to be able to separate them into non-instructional methods of business logic, and then change these behaviors without affecting the code of the business logic.This solution is also called the proxy mechanism.

To understand the concepts of AOP, the Spring reference manual defines the following important concepts of AOP, which are analyzed in conjunction with the above code:

  • Aspect (Aspect): The official abstraction is defined as "a focus of modularity, this concern may be crosscutting multiple objects", in this case, "tangent" is the specific behavior of the class Testaspect, for example, Aserviceimpl.bara () Call is one of the behaviors that the tangent testaspect is concerned about. "Slices" are configured in the ApplicationContext <aop:aspect>.
  • connection point (Joinpoint) : A behavior that is performed during the execution of a program, such as a call to a userservice.get or a userservice.delete throwing an exception.
  • notification (Advice) : The action that "slice" produces for a "connection point", for example, the action of logging the methods of all classes under the Com.spring.service package in Testaspect is a Advice. Where a "slice" can contain multiple "Advice", such as Serviceaspect.
  • pointcut (Pointcut) : An assertion that matches a connection point, a notification in AOP, and a Pointcut expression association. For example, all the notifications in Testaspect are concerned with connection points that are execution by pointcut expressions (* com.spring.service.*.* (..)) to decide.
  • target Object : An object that is notified by one or more facets. For example, Aservcieimpl and Bserviceimpl, of course, when actually running, Spring AOP takes the proxy implementation, the actual AOP operation is TargetObject proxy object.
  • AOP Proxy : There are two kinds of proxy methods in spring AOP, JDK dynamic agent and cglib agent. By default, when the TargetObject implements an interface, the JDK dynamic agent is used, for example, Aserviceimpl; Conversely, cglib proxies, for example, Bserviceimpl. Forcing the Cglib agent to use the Proxy-target-class property of <aop:config> is set to true.

Notification (Advice) type:

    • Forward notification (before advice): A notification that was executed before a connection point (Joinpoint), but this notification does not prevent execution before the connection point. The ApplicationContext uses <aop:before> elements to declare in <aop:aspect>. For example, the Dobefore method in Testaspect.
    • Post notification (after advice): the notification that is executed when a connection point exits (whether it is a normal return or an unexpected exit). The ApplicationContext uses <aop:after> elements to declare in <aop:aspect>. For example, the Returnafter method in Serviceaspect, so the Returnafter method is still executed when Userservice.delete throws an exception in Teser.
    • Notification after return (after return advice): A notification that is executed after a connection point has completed normally, and does not include cases where an exception was thrown. The ApplicationContext uses <after-returning> elements to declare in <aop:aspect>.
    • Wrapping Notification (Around advice): A notification that surrounds a connection point, similar to the Dofilter method of the filter in the servlet specification in the Web. You can customize the behavior before and after the call to the method, or you can choose not to execute. The ApplicationContext uses <aop:around> elements to declare in <aop:aspect>. For example, the around method in Serviceaspect.
    • Notification After an exception is thrown (after throwing advice): the notification that is executed when the method throws an unexpected exit. The ApplicationContext uses <aop:after-throwing> elements to declare in <aop:aspect>. For example, the Returnthrow method in Serviceaspect.

Note: Multiple notifications can be applied to a target object, that is, multiple facets can be woven into the same target object.

The use of spring AOP can be based on two ways, one is more convenient and powerful annotation, the other is a good way to configure the XML.

To start with annotations, use annotations to configure Spring AOP as a whole in two steps:

The first step is to declare the activation of the auto-scan component feature in the XML file, while activating the automatic proxy feature (while adding a userservice common service layer component to the XML to test the annotation functionality of AOP):

<?XML version= "1.0" encoding= "UTF-8"?><Beansxmlns= "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/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 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-3.0.xsd " >    <!--activates component scanning to automatically scan components configured with annotations under package CN.YSH.STUDIO.SPRING.AOP and its sub-packages -    <Context:component-scanBase-package= "CN.YSH.STUDIO.SPRING.AOP"/>    <!--activating the automatic proxy feature -    <Aop:aspectj-autoproxyProxy-target-class= "true"/>        <!--User Service Object -    <BeanID= "UserService"class= "Cn.ysh.studio.spring.aop.service.UserService" /></Beans>
The second step is to add annotations to the Aspect slice class:
 PackageCn.ysh.studio.spring.aop.aspect;ImportOrg.apache.commons.logging.Log;Importorg.apache.commons.logging.LogFactory;ImportOrg.aspectj.lang.JoinPoint;ImportOrg.aspectj.lang.ProceedingJoinPoint;ImportOrg.aspectj.lang.annotation.After;Importorg.aspectj.lang.annotation.AfterReturning;Importorg.aspectj.lang.annotation.AfterThrowing;ImportOrg.aspectj.lang.annotation.Around;ImportOrg.aspectj.lang.annotation.Aspect;ImportOrg.aspectj.lang.annotation.Before;ImportOrg.aspectj.lang.annotation.Pointcut;Importorg.springframework.stereotype.Component;/*** System service component Aspect slice Bean *@author* @date 2017-3-28*///declares that this is a component@Component//declares that this is a slice bean@Aspect Public classServiceaspect {Private Final StaticLog log = Logfactory.getlog (serviceaspect.class); //configuration Pointcut, this method has no method body, mainly for the convenience of other methods in the same way to use the pointcut configured here@Pointcut ("Execution (* cn.ysh.studio.spring.aop.service). *(..))")     Public voidaspect () {}/** Configuring the pre-notification, using the Pointcut registered on method aspect () * Accepts the Joinpoint Pointcut object at the same time, can not have this parameter*/@Before ("Aspect ()")     Public voidbefore (Joinpoint joinpoint) {if(log.isinfoenabled ()) {Log.info ("Before" +joinpoint); }    }        //Configuring the Post notification, using the Pointcut registered on method aspect ()@After ("aspect ()")     Public voidAfter (Joinpoint joinpoint) {if(log.isinfoenabled ()) {Log.info ("After" +joinpoint); }    }        //configure surround notifications, using Pointcuts registered on method aspect ()@Around ("aspect ()")     Public voidAround (joinpoint joinpoint) {LongStart =System.currenttimemillis (); Try{((proceedingjoinpoint) joinpoint). proceed (); LongEnd =System.currenttimemillis (); if(log.isinfoenabled ()) {Log.info ("Around" + Joinpoint + "\tuse Time:" + (End-start) + "ms!"); }        } Catch(Throwable e) {LongEnd =System.currenttimemillis (); if(log.isinfoenabled ()) {Log.info ("Around" + Joinpoint + "\tuse Time:" + (End-start) + "Ms with exception:" +e.getmessage ()); }        }    }        //Configure a post-return notification using a Pointcut registered on method aspect ()@AfterReturning ("aspect ()")     Public voidAfterreturn (Joinpoint joinpoint) {if(log.isinfoenabled ()) {Log.info ("Afterreturn" +joinpoint); }    }        //Configuring a notification after throwing an exception, using a Pointcut registered on method aspect ()@AfterThrowing (pointcut= "aspect ()", throwing= "ex")     Public voidAfterthrow (Joinpoint joinpoint, Exception ex) {if(log.isinfoenabled ()) {Log.info ("Afterthrow" + joinpoint + "\ T" +ex.getmessage ()); }    }    }

Test code:

 PackageCN.YSH.STUDIO.SPRING.AOP;ImportOrg.apache.commons.logging.Log;Importorg.apache.commons.logging.LogFactory;ImportOrg.springframework.context.ApplicationContext;ImportOrg.springframework.context.support.ClassPathXmlApplicationContext;ImportCn.ysh.studio.spring.aop.service.UserService;ImportCn.ysh.studio.spring.mvc.bean.User;/*** Spring AOP Test *@author* @date 2017-3-28*/ Public classTester {Private Final StaticLog log = Logfactory.getlog (Tester.class);  Public Static voidMain (string[] args) {//start the spring containerApplicationContext context =NewClasspathxmlapplicationcontext ("Applicationcontext.xml"); //Get Service componentUserService service = (userservice) context.getbean ("UserService"); //three ways to invoke the UserService object in a normal wayUser user = Service.get (1L);        Service.save (user); Try{service.delete (1L); } Catch(Exception e) {if(log.iswarnenabled ()) {Log.warn ("Delete User:" +e.getmessage ()); }        }    }}

The test results are as follows:

INFO [spring.aop.aspect.serviceaspect:40] before execution (User Cn.ysh.studio.spring.aop.service.UserService.get (Long) INFO [spring.aop.service.UserService:19] GetUser Method ... INFO [Spring.aop.aspect.ServiceAspect:Around Execution (User cn.ysh.studio.spring.aop.service.UserService.get (Long)) Use time:42 ms!INFO [Spring.aop.aspect.ServiceAspect:After execution (User cn.ysh.studio.spring.aop.service.UserService.get (Long) INFO [spring.aop.aspect.ServiceAspect:Afterreturn Execution (User cn.ysh.studio.spring.aop.service.UserService.get (Long) INFO [spring.aop.aspect.ServiceAspect:Before Execution (voidCn.ysh.studio.spring.aop.service.UserService.save (User)) INFO [Spring.aop.service.UserService:26] Saveuser Method ... INFO [Spring.aop.aspect.ServiceAspect:] Around execution (voidCn.ysh.studio.spring.aop.service.UserService.save (User)) use Time:2 ms!INFO [Spring.aop.aspect.ServiceAspect:After execution (voidCn.ysh.studio.spring.aop.service.UserService.save (User)) INFO [Spring.aop.aspect.ServiceAspect:Afterreturn Execution (voidCn.ysh.studio.spring.aop.service.UserService.save (User)) INFO [Spring.aop.aspect.ServiceAspect:Before Execution (BooleanCn.ysh.studio.spring.aop.service.UserService.delete (Long) INFO [spring.aop.service.UserService:32] Delete Method ... INFO [Spring.aop.aspect.ServiceAspect:] Around execution (BooleanCn.ysh.studio.spring.aop.service.UserService.delete (Long)) Use Time:5ms with exception:spring AOP throwadvice demo INFO [spring.aop.aspect.ServiceAspect:After execution (BooleanCn.ysh.studio.spring.aop.service.UserService.delete (Long) INFO [spring.aop.aspect.ServiceAspect:Afterreturn Execution (BooleanCn.ysh.studio.spring.aop.service.UserService.delete (Long)) WARN [Studio.spring.aop.Tester:Delete User:nullreturnValue from advice does not match primitivereturnType for: Public BooleanCn.ysh.studio.spring.aop.service.UserService.delete (Long)throwsJava.lang.Exception
You can see that, as we expected, although we did not make any changes to the Userserivce class including its invocation, spring still intercepts the invocation of the method, which is perhaps the magic of AOP.

Annotation-based spring AOP configuration and usage

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.