Spring AOP surround notification based on @aspectj

Source: Internet
Author: User
Tags aop documentation

Objective:

There are two important differences between Spring's surround notification and pre-notification, and the post-notification:

1) The invocation of the target method is determined by the surround notification, that is, you can decide whether to invoke the target method, and the pre-and post-notification is not determined, they just execute the notification before and after the method's call, that is, the target method is definitely to be executed.

2) surround notification controls the return object, which means you can return a completely different return value from the target object, although it is dangerous, but you can do it. The latter method cannot be done because it is called after the target method returns a value

Here is an example of my own testing that uses face-to-surface to handle some common questions, such as permissions management, the delegation of a transaction

The following example is the use of surround notification, when the program is an exception, repeated submission of the request, the number of repetitions can be set

When we develop an enterprise application, we typically want to refer to a set of modular applications and specific operations from a few facets, and here is a typical general section that might look like this (which is also in the spring documentation)

Package test.prefer.aspect;

Import Org.aspectj.lang.annotation.Aspect;
Import Org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Systemarchitecture {

/**
* A join point was in the Web layer if the method is defined
* In a type in the Com.xyz.someapp.web package or any sub-package
* under that.
*/
@Pointcut ("Within (com.xyz.someapp.web. *)")
public void Inweblayer () {}

/**
* A join point was in the service layer if the method is defined
* In a type in the Com.xyz.someapp.service package or any sub-package
* under that.
*/
@Pointcut ("Within (com.xyz.someapp.service. *)")
public void Inservicelayer () {}

/**
* A join point was in the data access layer if the method is defined
* In a type in the Com.xyz.someapp.dao package or any sub-package
* under that.
*/
@Pointcut ("Within (Com.xyz.someapp.dao. *)")
public void Indataaccesslayer () {}

/**
* A business service was the execution of any method defined on A service
* interface. This definition assumes that interfaces is placed in the
* "Service" package, and that implementation types is in Sub-packages.
*
* If you group service Interfaces by functional area (for example,
* In Packages Com.xyz.someapp.abc.service and Com.xyz.def.service) then
* The Pointcut expression "execution (* com.xyz.someapp). Service.*.* (.. ))"
* could be used instead.
*
* Alternatively, you can write the expression using the ' bean '
* PCD, like so "Bean (*service)". (This assumes
* Named your Spring service beans in a consistent fashion.)
*/
@Pointcut ("Execution (* test.prefer.aspect.*.* (..))")
public void Businessservice () {}

/**
* A data access operation is the execution of any method defined on A
* DAO interface. This definition assumes that interfaces is placed in the
* "DAO" package, and that implementation types is in Sub-packages.
*/
@Pointcut ("Execution (* com.xyz.someapp.dao.*.* (..))")
public void Dataaccessoperation () {}

}

I. Define one of your own facets

/*
* File name: Concurrentoperationexecutor.java
* Description:< Description >
* Modified by: Administrator
*/

Package test.prefer.aspect;

Import Org.aspectj.lang.ProceedingJoinPoint;
Import Org.aspectj.lang.annotation.Around;
Import Org.aspectj.lang.annotation.Aspect;
Import org.springframework.core.Ordered;

/**
* @author
* @date 2010-6-1
*/
@Aspect
public class Concurrentoperationexecutor implements Ordered {

private static final int default_max_retries = 2;

private int maxretries = default_max_retries;
private int order = 1;

public void setmaxretries (int maxretries) {
This.maxretries = maxretries;
}

public int GetOrder () {
return this.order;
}
public void Setorder (int order) {
This.order = order;
}

@Around ("Test.prefer.aspect.SystemArchitecture.businessService ()")
Public Object doconcurrentoperation (Proceedingjoinpoint pjp) throws Throwable {
Surround Notification processing methods
int numattempts = 0;
Exception lockfailureexception;
do {
numattempts++;
try {
SYSTEM.OUT.PRINTLN ("Surround notification method [Doconcurrentoperation (Proceedingjoinpoint PJP)] ...");;
return Pjp.proceed ();
}
catch (Exception ex) {
Lockfailureexception = ex;
}
}
while (numattempts <= this.maxretries);
Throw lockfailureexception;
}

}

Description

Note that the facets implement the Ordered interface so that we can prioritize the tangent to the transaction notification (we want to do it in a completely new transaction each time we try again). Both the maxretries and the order properties can be configured in spring. The main action takes place in Doconcurrentoperation, the wrapping notification method. Please note that all of our businessservice () methods will use this retry policy at this time. We'll try to deal with it first, and if we get a exception exception, we'll just retry until we run out of all the preset retries (Spring development documentation)

Second, configure the section in the configuration file.

<aop:aspectj-autoproxy/>

<bean id= "Concurrentoperationexecutor"
class= "Test.prefer.aspect.ConcurrentOperationExecutor" >
<property name= "Maxretries" value= "3"/>
<property name= "order" value= "/>"
</bean>

All right, let's try the results here.

Third, the test effect

1) Create a new test Bean:mytestaspect with the following code:

Package test.prefer.aspect;
/**
* This is a slice class
*/
Import Org.aspectj.lang.annotation.Aspect;

public class Mytestaspect {
int k=0;
public void Test (String args) throws exception{
System.out.println ("Here is [target] method Test ()" + ++k);
if (k<2) {
throw new Exception ();
}

}

}

This class must be under the package or sub-package of the connection point,

There's a definition in systemarchitecture.

@Pointcut ("Execution (* test.prefer.aspect.*.* (..))")
public void Businessservice () {}

2) applicationcontext.xml Configuration Mytestaspect

<bean id= "test" class= "Test.prefer.aspect.MyTestAspect"/>

3) All right, look at the effect.

Package test;

Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
Import Test.prefer.aspect.MyTestAspect;

public class Example {

public static void Main (String args[]) {

ApplicationContext CTX = new Classpathxmlapplicationcontext ("Applicationcontext.xml");
Mytestaspect t = (mytestaspect) ctx.getbean ("test");
try{
T.test ("");
}catch (Exception e) {
System.out.println ("main () Handles exception" +e);
}
}

}

The output is:

The surround notification method [Doconcurrentoperation (Proceedingjoinpoint PJP)] .....
Here is the [target] method test () 1
The surround notification method [Doconcurrentoperation (Proceedingjoinpoint PJP)] .....
Here is the [target] method Test ()

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.