Spring annotation-based version of the AOP

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_43687990/article/details/102640880

About AOP
AOP (Aspect-Oriented Programming, Aspect Oriented Programming): It is a supplement to object-oriented programming. Its main target is the programming section. In the application programming AOP still need to define public function, but you can clearly define the function in which place, in what way the application, and do not have to modify the affected class, this way, it is modularized crosscutting concerns specific to the section in the.
AOP in terms of
section (Aspect): crosscutting concerns (functionality across multiple application modules) is modular particular object
notification (Advice): section must be completed work
objects to be notified: Target (Target)
Agent (Proxy): application objects created after notification to the target object
connection point (Joinpoint): a specific program execution location: in front of a class as a method call, after call, after the method throws an exception and so on. The connection point is determined by the two information: a program execution point representation method; orientation opposite points indicated. E.g. ArithmethicCalculator # add () method of the connection point before execution, execution point ArithmethicCalculator # add (); orientation position before performing a method for
cutting point (the pointcut): Each class has a plurality of connection points: for example all the ArithmethicCalculator the method of actually connecting point, i.e. the point of attachment is to the class of an objective transaction. AOP to a specific point of attachment through the tangent point. Analogy: the connection point corresponding to records in the database, the point of tangency corresponding to the query condition. Tangent point and the connection point is not the one to one relationship, a plurality of connection points matching the cut point, the tangent point described by org.springframework.aop.Pointcut interfaces, classes and methods which use as a query point of attachment.

Spirng in the use of AOP

Spring in the use of the Java community is the most complete of the most popular AOP framework by @AspectJ comment

To use AspectJ annotation in Spring, AspectJ library must be added: aopalliance.jar, aspectj.weaver.jar and spring-aspects.jar
start @AspectJ Spring support for annotations in the configuration file, configuration is as follows

<!--使@AspectJ注解生效-->
<!--当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时, 会自动为与 AspectJ 切面匹配的 Bean 创建代理.-->
<aop:aspect-autoproxy></aop:aspect-autoproxy>

Note that the configuration file needs to be added aop namespace

xmlns:aop=“http://www.springframework.org/schema/aop”

Section with AspectJ annotation statement

To declare AspectJ aspects in Spring, just as Bean instances in the declaration section IOC container. After initialization AspectJ aspects in Spring IOC container, Spring IOC container will create a proxy for those with AspectJ aspect that match Bean
in AspectJ annotation, cut with just a Java class @Aspect annotations.

AspectJ supports five types of notification

Notification is marked with a simple method for some java annotations. AspectJ supports the following five types of notification

@Before: Before advice, executed before the method execution
@After: Rear notice, executed after execution method
@AfterRunning: return notice, returned after execution method results in
@AfterThrowing: abnormal notification method throws an exception after
@Around : around advice, execute around method

Sample Code

//准备一个接口

public interface CalculatorInterface {
	int add(int i , int j);
	int sub(int i , int j);
	int mul(int i , int j);
	int div(int i , int j);
	
}

//实现上面的接口
@Component
public class CalculatorImpl implements  CalculatorInterface{

	@Override
	public int add(int i, int j) {
		int resault = i + j;
		
		return resault;
	}

	@Override
	public int sub(int i, int j) {
		int resault = i - j;

		return resault;
	}

	@Override
	public int mul(int i, int j) {
		int resault = i * j;
	
		return resault;
	}

	@Override
	public int div(int i, int j) {
		int resault = i / j;
		
		return resault;
	}

//下面是实现aop的类

@Aspect
@Component
public class TestAspect(){
	
	/*
	前置通知:在方法执行前执行的通知,使用@Before注解,并将切入点表达式的值作为注解值
	execution (public int com.hist.aop.CalculatorInterface.add(int,int))为切点表达式,切点表达式表示执行 CalculatorInterface
接口的 add() 方法。可以用*号代替,表示执行CalculatorInterface下的所有符合参数类型为两个int的方法
		JoinPoint 可以获得方法的详细信息
	*/
	@Before("execution (public int com.hist.aop.CalculatorInterface.add(int,int))")
	public void beforeMethod(JoinPoint joinPoint){
	System.out.println(joinPoint.getSignature().getName() ); //获得所执行方法的名字
	Object [] args = joinPoint.getArgs();//获得方法的所有参数
	}

/*
后置通知:在返回结果或抛出异常的时候执行。一个切面可以包括多个通知
*/
@After("execution(public int com.hist.aop.CalculatorInterface.*(int,int))")
public void AfterMethod(JoinPoint joinPoint){
	System.out.println(joinPoint.getSingnature().getName()); 
}

/*
返回通知:无论连接点是正常返回还是抛出异常,后置通知都会执行,但返回通知只有在正常返回时才会执行
在返回通知中, 只要将 returning 属性添加到 @AfterReturning 注解中, 就可以访问连接点的返回值. 该属性的值即为用来传入返回值的参数名称. 
必须在通知方法的签名中添加一个同名参数. 在运行时, Spring AOP 会通过这个参数传递返回值
切入点表达式中,..匹配任意参数
*/
@AfterReturning(returning="result",value="execution(public int com.hist.aop.CalculatorInterface.*(..))")
public void returningMethod(JoinPoint joinPoint,Object result){
System.out.println("method = "+joinPoint.getSignature().getName());

System.out.println("The method result = "+ result);
}

	/*
	异常通知:只在连接点抛出异常时才执行异常通知
	将 throwing 属性添加到 @AfterThrowing 注解中, 也可以访问连接点抛出的异常. Throwable 是所有错误和异常类的超类. 所以在异常通知方法可以捕获到任何错误和异常.
	如果只对某种特殊的异常类型感兴趣, 可以将参数声明为其他异常的参数类型. 然后通知就只在抛出这个类型及其子类的异常时才被执行
	*/
	@AfterThrowing(value="execution(public int com.hist.aop.CalculatorInterface.*(..))",throwing="ex")
	public void exectionMethod(JoinPoint joinPoint,NullPointerException ex) {
		System.out.println("method = "+joinPoint.getSignature().getName());
		System.out.println("Exception ="+ex);
	}
/*
环绕通知:环绕通知是所有通知类型中功能最为强大的, 能够全面地控制连接点. 甚至可以控制是否执行连接点.
对于环绕通知来说, 连接点的参数类型必须是 ProceedingJoinPoint . 它是 JoinPoint 的子接口, 允许控制何时执行, 是否执行连接点.
在环绕通知中需要明确调用 ProceedingJoinPoint 的 proceed() 方法来执行被代理的方法. 如果忘记这样做就会导致通知被执行了, 但目标方法没有被执行.
注意: 环绕通知的方法需要返回目标方法执行之后的结果, 即调用 joinPoint.proceed(); 的返回值, 否则会出现空指针异常
*/

@Around("execution(public int com.hist.aop.CalculatorInterface.*(..))")
public Objecta roundMethod(ProceedingJoinPoint joinPoint){
Object result = null;
try{
//前置通知
			System.out.println("The method "+joinPoint.getSignature().getName()+" begain");

//执行方法
result = joinPoint.proceed();
//返回通知
			System.out.println("The method "+joinPoint.getSignature().getName()+" end with"+result);


}catch(Throwable e){
//异常通知
	System.out.println("The method throw Exection= "+e);
			throw new RuntimeException("find a Exception ");

}
//后置通知
System.out.println("这是后置通知");
}

}

Using the method signature can be written in AspectJ pointcut expression
to match the most typical entry point expression signature method according to various methods:
Execution * com.atguigu.spring.ArithmeticCalculator. (...): matches all methods declared in ArithmeticCalculator , * represents any of a modifier and any return value. * represents any second method. ... match any number of parameters. If the target class and the interface section in the same package, package name may be omitted.
Execution public ArithmeticCalculator *.
(...): all public methods in matching ArithmeticCalculator interface.
Execution public double ArithmeticCalculator. (...): ArithmeticCalculator matching method returns the value of double type
Execution public double ArithmeticCalculator.
(double, ...): the first parameter is a match the method of double type, ... matches an arbitrary number of parameters of any type of
execution public double ArithmeticCalculator * (double, double):. matching parameter of type double, double types.
Reuse entry point, the sample code:

	/*
	 * 使用@Pointcut实现切点重用,在通知中通过方法名引用
	 */
	@Pointcut("execution (public int com.hist.aop.CalculatorInterface.*(int,int))")
	public void JoinPointExpression() {}

Reuse entry point is to use the notification of "execution (public int com.hist.aop.CalculatorInterface * (int, int).)" Expression transposition method name: "JoinPointExpression ()"

Multiple facets of priority
in the application of more than one cut on the same connection point, unless explicitly specified otherwise, their priority is uncertain.
Cut priority can be specified by implementing the Ordered interface or use @Order comment.
Realization Ordered returns an interface, getOrder () method is the smaller the value, the higher the priority.
If used @Order annotation number in comment
Here Insert Picture Description
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/qq_43687990/article/details/102640880
Recommended