[Spring practice series] (18) annotation Section
Using annotations to create a plane is a key feature introduced by AspectJ 5. Before AspectJ 5, writing the AspectJ section requires learning a Java Language extension. However, the AspectJ annotation-oriented model can easily transform any class into a section using a few annotations. Looking back at the Audience class, there is nothing to make it a cut-off, and we have to use XML to declare notifications and cut points. Through the @ AspectJ annotation, let's look at the Audience class, which can be converted into a cut surface without any additional class or Bean declaration.
package com.sjf.bean;
/**
* Artist entity
* @author sjf0115
*
*/
public class Singer {
public void perform() {
System. out. println ("A personal concert ...");
}
}
package com.sjf.bean;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* Viewer entity class (annotation is cut)
* @author sjf0115
*
*/
@Aspect
public class Audience {
// Define the cut point
@Pointcut("execution(* com.sjf.bean.Singer.perform(..))")
public void SingerPerform(){
// Empty Method
}
// Before the performance
@Before("SingerPerform()")
public void takeSeats(){
System.out.println("the audience is taking their seats...");
}
// After the show is successful
@AfterReturning("SingerPerform()")
public void applaud(){
System.out.println("very good, clap clap clap...");
}
// After the performance fails
@AfterThrowing("SingerPerform()")
public void demandRefund(){
System.out.println("very bad, We want our money back...");
}
}The new Audience class is now labeled using the @ AspectJ annotation. This annotation indicates that Audience is not only a POJO, but also a aspect. The @ Pointcut annotation is used to define a cut point that can be reused in the @ AspectJ section. The value of @ Pointcut annotation is an AspectJ cut point expression (the cut point must match the Singer's perform () method ). The vertex name is from
Method Name. Because the cut point is named SingerPerform (). The actual content of the SingerPerform () method is not important. It is only an identifier for @ Pointcut annotation attachment. Every method of Audience is marked with notification annotations. The takeSeats () method uses the @ Before annotation to indicate that they are pre-notification methods. The applaud () method uses the @ AfterReturning annotation to indicate that it is a post-notification method. The demandRefund () method uses the @ AfterThrowing annotation to indicate that the method will be called when an exception is thrown. The SingerPerform () Cut Point name is assigned to all notification annotations as the parameter value to indicate where each notification method should be applied.
Note:
Except annotations and the unoperated SingerPerform () method, the Audience class is not changed in implementation, and the Audience class is still a simple Java object, can be used as before (Bean is used for configuration in Spring ). |
Because the Audience class contains all the cut points and notifications that it needs to define, we do not need to declare the cut points and notifications in the XML configuration. To enable Spring to apply Audience to a specific aspect, we need to declare an automatic proxy Bean in the Spring context. The Bean knows how to convert the Bean labeled by @ AspectJ annotation into a proxy notification. Therefore, Spring comes with an automatic proxy creation class named AnnotationAwareAspectJProxyCreator. In the Spring context, we can register AnnotationAwareAspectJProxyCreator as a Bean. However, the class text is too long to be used. Therefore, we use Spring's
Aop SpaceProvides a custom configuration element () to replace the former, which is easier to use.
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-4.2.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.xsd">
The configuration element will create an AnnotationAwareAspectJProxyCreator class in the Spring context, which will automatically proxy some beans. These Bean methods need to match the tangent points defined in the Bean annotated with @ AspectJ.
Running result:
theaudienceistakingtheirseats...Playing a personal concert...verygood,clapclapclap... |
Note:
Both the element and the @ AspectJ annotation form an effective way to convert a POJO into a plane. However, an obvious advantage of @ AspectJ is that code that does not need to implement the aspect function (in this example, the Audience class code ). Through @ AspectJ, We must mark the class and method, which requires the source code |
1. annotation surround notification
Like Spring's XML-based AOP, the use of @ AspectJ annotations is not only limited to defining pre-and post-notification types. We can also create surround notifications.
@Around("SingerPerform()")
public void PerformTime(ProceedingJoinPoint joinPoint){
// Before the show System.out.println("the audience is taking their seats..."); try { long start = System.currentTimeMillis();// Perform the performance operation joinPoint.proceed(); long end = System.currentTimeMillis();// Successful performance System.out.println("very good, clap clap clap...");System. out. println ("this performance requires" + (end-start) + "milliseconds "); } catch (Throwable e) {// Performance failed System.out.println("very bad, We want our money back..."); e.printStackTrace(); } }
Here, the @ Around annotation indicates that the notify mtime () method will be used as the surround notification application and SingerPerform () Cut Point. The only difference from the previous XML method is the annotation marked with @ Around. Simply using the @ Around annotation to annotate a method is not enough to call the proceed () method. Therefore, the method that is surrounded by notifications must accept a ProceedingJoinPoint object as the method input parameter, and call the proceed () method on the object.
2. Pass parameters to the marked notification
Previously, we used Spring XML-based section declaration as the notification transmission parameter, but the @ AspectJ annotation as the notification transmission parameter, which is not much different from that.
package com.sjf.bean;
/**
* Artist entity * @author sjf0115 * */public class Singer { public void perform(String song) {System. out. println ("A personal concert..." + song ); }}
package com.sjf.bean;
import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;/*** Organizer entity class * @author sjf0115 * */@Aspectpublic class Organizers { // Define the cut point @Pointcut("execution(* com.sjf.bean.Singer.perform(String)) and args(song)") public void SingerPerform(){ // }// Before the performance @Before("SingerPerform() and args(song)") public void BeforeSong(String song){System. out. println ("the concert is about to begin, and the singing song is" + song ); }}
The element changes to the @ Pointcut annotation, And the element changes to the @ Before annotation.
I don't know how to solve the following configuration error? Solving .....
// Define the cut point
@Pointcut("execution(* com.sjf.bean.Singer.perform(String)) and args(song)")
public void SingerPerform(String song){ // }// Before the performance @Before("SingerPerform(song)") public void BeforeSong(String song){System. out. println ("the concert is about to begin, and the singing song is" + song ); }
Source: Spring practice