Spring Aop (2) - Simple implementation of Spring Aop based on Aspectj annotations

2 Simple implementation of Spring Aop based on Aspectj annotations

Spring Aop is implemented based on the Aop framework Aspectj. It does not completely extend and transform the Aspectj framework, but uses some functions in Aspectj to implement its own Aop framework, including the parsing of the annotations provided by Aspectj. The differences between Spring Aop and Aop implemented by Aspectj have been mentioned before, so I won't repeat them here. This article mainly describes how to use the annotations provided by Aspectj to implement Spring Aop functions, aiming to give you a preliminary impression of Spring Aop and the use of Aspectj annotations to develop Spring Aop.

2.1 Enable support for Aspectj annotations

When using Aspectj annotations to implement Spring Aop, we first need to enable Spring's support for Aspectj annotations, which is done through configuration. When our Spring configuration is based on configuration files, we can <aop:aspectj-autoproxy/>enable support for Aspectj annotations by introducing aop-related schemas in Spring's configuration files.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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/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
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

	<context:annotation-config/>
	< context : component-scan  base-package = " com.elim.test " />
	 <!-- enable support for Aspectj annotations --> 
    < aop : aspectj-autoproxy />

</beans>

When our configuration is done through a configuration class annotated with @Configuration, we can enable support for Aspectj annotations by annotating the configuration class with @EnableAspectJAutoProxy.

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

2.2 Define the aspect class

Defining an aspect class is relatively simple, you only need to define a simple class that is annotated with @Aspect. @Aspect is a marker for Spring Aop to identify aspect classes, but it is not enough to use @Aspect to annotate aspect classes. Because Spring Aop can only work on beans defined in the bean container, the corresponding aspect class must also be found when the bean object is defined in the bean container. @Aspect does not have the function of letting Spring scan it by default and instantiate the corresponding class as a Spring bean, so we must define the bean in the bean container. It can be defined through a configuration file, or annotated with @Component, etc.

@Aspect
@Component
public class MyAspect {
	
}

Aspect classes annotated with @Aspect can also define common properties and methods like common classes, and can also be used as a common bean if necessary.

2.3 Define Pointcut

Pointcut is used to define the JoinPoint that the aspect class needs to function. In Spring Aop, these JoinPoints are actually some method executions that we need to cut in, because we said earlier that Spring Aop only supports the execution of bean method execution. The core of Pointcut defined based on the Aspect annotation form is the @Pointcut annotation. We need to define a method with no return value in the Aspect class. The method type can be arbitrary, and then use @Pointcut to mark the method to indicate that it is a Pointcut definition , the corresponding method name indicates the name of the Pointcut. @Pointcut has a value property, which is usually an expression, through which you can specify the JoinPoint that the current Pointcut needs to act on. Expressions can be written in many ways, which will be explained later. The most commonly used is execution, which means the execution of a method. If we want to define the JoinPoint of a Pointcut as the execution of all add methods, then we can define it as follows.

@Aspect
@Component
public class MyAspect {

	@Pointcut("execution(* add(..))")
	private void pointcut() {}
	
}

2.4 Define Advice

Advice needs to be bound with Pointcut to define the operation that needs to be performed at the JoinPoint matching the specified Pointcut. There are three main types of Advice, before, after and around, and Aspectj supports them with corresponding annotations. The advice definition based on Aspectj annotations is specified by the corresponding annotations. We need to define a method in the aspect class, and then use the corresponding annotations to mark the method. The corresponding advice annotation has a value attribute, which we need to specify the Pointcut bound to it. The corresponding Pointcut needs to be specified by the full name of the class defined by Pointcut. The method name () is specified, if it is defined in the current aspect class Pointcut can omit the corresponding class name. Here we mainly take before as an example. As follows, we define a method before in the aspect class, annotate the method with the @Before annotation, and specify the bound Pointcut as the pointcut defined in the same aspect class.

@Aspect
@Component
public class MyAspect {

	@Pointcut("execution(* add(..))")
	private void pointcut() {}
	
	@Before("com.elim.test.spring.aop.MyAspect.pointcut()")
	private void before(JoinPoint joinPoint) {
		System.out.println(joinPoint.getTarget() + "----------------------Before---------------------");
	}
	
}

So far, when we access the add method of any bean object in the Spring bean container, we will call the before method defined in the MyAspect aspect class.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {

	@Autowired
	private UserService userService;
	
	@Test
	public void test1() {
		User user = new User(1, "ZhangSan");
		userService.add(user);
	}
	
}

(Note: This article is based on Spring 4.1.0, written on Monday, September 5, 2016)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326223775&siteId=291194637