Spring AOP details

Source: Internet
Author: User
Previously, the use of AOP was limited to declarative transactions. In addition, no problems related to it have been encountered in actual development. Recently, the project encountered the following requirements. After careful consideration, I thought we should use AOP to solve the problem. One is to solve the problem in a more flexible way, and the other is to take this opportunity to learn more about Spring AOP. This article is my own AOP study notes. The following requirements cannot be solved without AOP. As to whether the meeting is too far-fetched, the benevolent sees the wise and the wise sees the wise.
  1. Logs some function calls to observe the function calls of specific problems during operation.
  2. Important functions of monitoring. If a specified exception is thrown, you must notify the relevant personnel by SMS or email.
  3. Execution time of some important functions of financial control

In fact, the above requirements can be done without AOP, but they are quite depressing in the implementation process.

  1. The functions that need to print logs are scattered in each package. Only all function bodies can be found and logs can be manually added. However, these logs are temporary. After the problem is solved, clear the log printing code. You can only manually clear logs again!
  2. Similar to the case of 1, there are too many exceptions to be caught. If you want to manually add it, it is very likely that you have to manually clear it tomorrow, and you can only sweat. OK. This requirement is relatively fixed and belongs to the long-term monitoring category. It does not need to be added on time before being cleared. However, the customer requested to change 20% of exceptions to SMS reminders one day, and the remaining 80% to email reminders. Changed. Two days later, the customer complained that there were too many text messages, and all of them were changed to email reminders...
  3. This requirement is usually used to monitor the execution time of some functions and determine the bottleneck of slow system execution. After the bottleneck is solved, the troubles are the same as the situation 1.

Finally, I made up my mind to use AOP to solve the problem! The Code is as follows:

 

Partition class TestAspect

Java code
  1. Package com. spring. aop;
  2. /**
  3. * Cut surface
  4. *
  5. */
  6. Public class TestAspect {
  7. Public void doAfter (JoinPoint jp ){
  8. System. out. println ("log Ending method :"
  9. + Jp. getTarget (). getClass (). getName () + "."
  10. + Jp. getSignature (). getName ());
  11. }
  12. Public Object doAround (ProceedingJoinPoint pjp) throws Throwable {
  13. Long time = System. currentTimeMillis ();
  14. Object retVal = pjp. proceed ();
  15. Time = System. currentTimeMillis ()-time;
  16. System. out. println ("process time:" + time + "ms ");
  17. Return retVal;
  18. }
  19. Public void doBefore (JoinPoint jp ){
  20. System. out. println ("log ining method :"
  21. + Jp. getTarget (). getClass (). getName () + "."
  22. + Jp. getSignature (). getName ());
  23. }
  24. Public void doThrowing (JoinPoint jp, Throwable ex ){
  25. System. out. println ("method" + jp. getTarget (). getClass (). getName ()
  26. + "." + Jp. getSignature (). getName () + "throw exception ");
  27. System. out. println (ex. getMessage ());
  28. }
  29. Private void sendEx (String ex ){
  30. // Send SMS or email notification to TODO
  31. }
  32. }

 

 

Java code
  1. Package com. spring. service;
  2. /**
  3. * Interface
  4. */
  5. Public interface AService {
  6. Public void fooA (String _ msg );
  7. Public void Merge ();
  8. }

Java code

  1. Package com. spring. service;
  2. /**
  3. * Implementation class of interface
  4. */
  5. Public class AServiceImpl implements AService {
  6. Public void upload (){
  7. System. out. println ("AServiceImpl. Digest ()");
  8. }
  9. Public void fooA (String _ msg ){
  10. System. out. println ("AServiceImpl. fooA (msg:" + _ msg + ")");
  11. }
  12. }

 

 

Java code
  1. Package com. spring. service;
  2. /**
  3. * Service Class B
  4. */
  5. Public class BServiceImpl {
  6. Public void barB (String _ msg, int _ type ){
  7. System. out. println ("BServiceImpl. barB (msg:" + _ msg + "type:" + _ type + ")");
  8. If (_ type = 1)
  9. Throw new IllegalArgumentException ("test exception ");
  10. }
  11. Public void fooB (){
  12. System. out. println ("BServiceImpl. fooB ()");
  13. }
  14. }

ApplicationContext

Java code
  1. <? Xml version = "1.0" encoding = "UTF-8"?>
  2. <Beans xmlns = "http://www.springframework.org/schema/beans"
  3. Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
  4. Xmlns: aop = "http://www.springframework.org/schema/aop"
  5. Xsi: schemaLocation ="
  6. Http://www.springframework.org/schema/beans
  7. Http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  8. Http://www.springframework.org/schema/aop
  9. Http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
  10. Default-autowire = "autodetect">
  11. <Aop: config>
  12. <Aop: aspect id = "TestAspect" ref = "aspectBean">
  13. <! -- Configure all methods of all classes or interfaces in the com. spring. service package -->
  14. <Aop: pointcut id = "businessService"
  15. Expression = "execution (* com. spring. service. *. * (..)"/>
  16. <Aop: before pointcut-ref = "businessService" method = "doBefore"/>
  17. <Aop: after pointcut-ref = "businessService" method = "doAfter"/>
  18. <Aop: around pointcut-ref = "businessService" method = "doAround"/>
  19. <Aop: after-throwing pointcut-ref = "businessService" method = "doThrowing" throwing = "ex"/>
  20. </Aop: aspect>
  21. </Aop: config>
  22. <Bean id = "aspectBean" class = "com. spring. aop. TestAspect"/>
  23. <Bean id = "aService" class = "com. spring. service. AServiceImpl"> </bean>
  24. <Bean id = "bService" class = "com. spring. service. BServiceImpl"> </bean>
  25. </Beans>

 

Test class AOPTest

Java code
  1. Public class AOPTest extends actdependencyinjectionspringcontexttests {
  2. Private AService aService;
  3. Private BServiceImpl bService;
  4. Protected String [] getConfigLocations (){
  5. String [] configs = new String [] {"/applicationContext. xml "};
  6. Return configs;
  7. }
  8. /**
  9. * Normal call
  10. */
  11. Public void testCall ()
  12. {
  13. System. out. println ("SpringTest JUnit test ");
  14. AService. fooA ("JUnit test fooA ");
  15. AService. Submit ();
  16. BService. fooB ();
  17. BService. barB ("JUnit test barB", 0 );
  18. }
  19. /**
  20. * Test After-Throwing
  21. */
  22. Public void testThrow ()
  23. {
  24. Try {
  25. BService. barB ("JUnit call barB", 1 );
  26. } Catch (IllegalArgumentException e ){
  27. }
  28. }
  29. Public void setAService (AService service ){
  30. AService = service;
  31. }
  32. Public void setBService (BServiceImpl service ){
  33. BService = service;
  34. }
  35. }

 

The running result is as follows:

Java code
  1. Log ining method: com. spring. service. AServiceImpl. fooA
  2. AServiceImpl. fooA (msg: JUnit test fooA)
  3. Log Ending method: com. spring. service. AServiceImpl. fooA
  4. Process time: 0 MS
  5. Log ining method: com. spring. service. AServiceImpl. Conflict
  6. AServiceImpl. Invoke ()
  7. Log Ending method: com. spring. service. AServiceImpl. Invoke
  8. Process time: 0 MS
  9. Log ining method: com. spring. service. BServiceImpl. fooB
  10. BServiceImpl. fooB ()
  11. Log Ending method: com. spring. service. BServiceImpl. fooB
  12. Process time: 0 MS
  13. Log ining method: com. spring. service. BServiceImpl. barB
  14. BServiceImpl. barB (msg: JUnit test barB type: 0)
  15. Log Ending method: com. spring. service. BServiceImpl. barB
  16. Process time: 0 MS
  17. Log ining method: com. spring. service. BServiceImpl. barB
  18. BServiceImpl. barB (msg: JUnit call barB type: 1)
  19. Log Ending method: com. spring. service. BServiceImpl. barB
  20. Method com. spring. service. BServiceImpl. barB throw exception
  21. Test exception

The Spring Reference Manual defines the following important concepts of AOP. The code is analyzed as follows:

  • Aspect: the official abstraction is defined as "modularity of a focus, which may cross multiple objects". In this example, the "aspect" is the specific behavior followed by TestAspect, for example, AServiceImpl. the call of lift () is one of the actions that concern TestAspect. "Aspect" is configured in ApplicationContext <aop: aspect>.
  • Joinpoint: a row in the program execution process is, for example, an AServiceImpl. Invoke () call or BServiceImpl. barB (String _ msg, int _ type) throws an exception.
  • Notification (Advice): the action taken by the "cut plane" for a "connection point", for example, com. spring. an Advice is used to record all the class methods in the service package. One slice can contain multiple "Advice", such as TestAspect.
  • Pointcut: an assertion that matches the connection point. In AOP, it is usually associated with a Pointcut expression. For example, the connection points of all notifications in TestAspect are determined by the entry point expression execution (* com. spring. service. *. * (...).
  • Target Object: The Object notified by one or more slices. For example, AServcieImpl and BServiceImpl, of course, Spring AOP adopts proxy implementation during actual running, and actual AOP operates on the proxy object of TargetObject.
  • AOP Proxy has two Proxy methods in Spring AOP: JDK dynamic Proxy and CGLIB Proxy. By default, when TargetObject implements an interface, JDK dynamic proxy is used, for example, AServiceImpl. Otherwise, CGLIB proxy is used, for example, BServiceImpl. To use the CGLIB proxy forcibly<aop:config>Ofproxy-target-classSet property to true

Notification (Advice) Type

  • Before advice: A notification executed Before a connection point. However, this notification cannot be executed Before a connection point. In ApplicationContext, use the <aop: before> element in <aop: aspect> for declaration. For example, the doBefore method in TestAspect
  • Post-notification (After advice): The Notification executed when a connection point exits (whether it is a normal return or an abnormal exit ). In ApplicationContext, use the <aop: after> element in <aop: aspect> for declaration. For example, the doAfter method in TestAspect, so when BServiceImpl. barB is called in AOPTest to throw an exception, the doAfter method is still executed
  • After return notification (After return advice): The Notification executed After a connection point is normal, excluding the exception thrown. In ApplicationContext, use the <after-returning> element in <aop: aspect> for declaration.
  • Around advice: notifications that enclose 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 method is called, or you can choose not to execute. In ApplicationContext, use the <aop: around> element in <aop: aspect> for declaration. For example, the doAround method in TestAspect.
  • After throwing advice: the notification that is executed when the method throws an exception and exits. In ApplicationContext, use the <aop: after-throwing> element in <aop: aspect> for declaration. For example, the doThrowing method in TestAspect.

Entry Point expression

  • Generally, the use of "execution" in the expression can meet most of the requirements. The expression format is as follows:
Java code
  1. Execution (modifiers-pattern? Ret-type-pattern declaring-type-pattern? Name-pattern (param-pattern) throws-pattern ?)

Modifiers-pattern: Operation permission of the Method

Ret-type-pattern: Return Value

Declaring-type-pattern: package where the method is located

Name-pattern: Method name

Parm-pattern: Parameter Name

Throws-pattern: exception

Among them, except ret-type-pattern and name-pattern, others are optional. In the preceding example, execution (* com. spring. service. *. *(..)) com. spring. under the service package, the return value is of any type; the method name is arbitrary; all methods with no restrictions on parameters.

  • Notification Parameters

You can bind parameters through args so that you can access specific parameters in the notification (Advice. For example, the configuration of <aop: aspect> is as follows:

Java code
  1. <Aop: config>
  2. <Aop: aspect id = "TestAspect" ref = "aspectBean">
  3. <Aop: pointcut id = "businessService"
  4. Expression = "execution (* com. spring. service. *. * (String,...) and args (msg,...)"/>
  5. <Aop: after pointcut-ref = "businessService" method = "doAfter"/>
  6. </Aop: aspect>
  7. </Aop: config>

The msg parameter can be accessed in the doAfter method of TestAspect, but in this way, the barB () in AService and BServiceImpl are no longer the connection points, because execution (* com. spring. service. *. * (String ,..)) only the method with the first parameter of the String type is configured. The doAfter method is defined as follows:

Java code
  1. Public void doAfter (JoinPoint jp, String msg)
  • Access the current connection point

Any notification (Advice) method can define the first parameterorg.aspectj.lang.JoinPointType.JoinPointInterfaces provide a series of useful methods, suchgetArgs()(Return method parameters ),getThis()(Return proxy object ),getTarget()(Return target ),getSignature()(Return information about the method being notified) andtoString()(Print out useful information about the method being notified.

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.