📅  最后修改于: 2020-12-04 07:53:48             🧑  作者: Mango
Spring框架建议您在基于Spring 1.2旧样式dtd的AOP实现上使用Spring AspectJ AOP实现,因为它为您提供了更多的控制并且易于使用。
有两种使用Spring AOP AspectJ实现的方法:
要了解aop概念及其优势等,请访问此处。AOP概念教程
Spring AspectJ AOP实现提供了许多注释:
用于创建建议的注释如下:
切入点是Spring AOP的一种表达语言。
@Pointcut批注用于定义切入点。我们也可以通过名称引用切入点表达式。让我们看一下切入点表达式的简单示例。
@Pointcut("execution(* Operation.*(..))")
private void doSomething() {}
切入点表达式的名称为doSomething()。无论返回类型如何,它将应用于Operation类的所有方法。
让我们尝试通过以下示例了解切入点表达式:
@Pointcut("execution(public * *(..))")
它将应用于所有公共方法。
@Pointcut("execution(public Operation.*(..))")
它将应用于Operation类的所有公共方法。
@Pointcut("execution(* Operation.*(..))")
它将应用于Operation类的所有方法。
@Pointcut("execution(public Employee.set*(..))")
它将应用于Employee类的所有公共设置方法。
@Pointcut("execution(int Operation.*(..))")
它将应用于返回int值的Operation类的所有方法。
在实际业务逻辑方法之前应用AspectJ Before Advice。您可以在此处执行任何操作,例如转换,身份验证等。
创建一个包含实际业务逻辑的类。
package com.javatpoint;
public class Operation{
public void msg(){System.out.println("msg method invoked");}
public int m(){System.out.println("m method invoked");return 2;}
public int k(){System.out.println("k method invoked");return 3;}
}
现在,创建包含在建议之前的方面类。
package com.javatpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation{
@Pointcut("execution(* Operation.*(..))")
public void k(){}//pointcut name
@Before("k()")//applying pointcut on before advice
public void myadvice(JoinPoint jp)//it is advice (before advice)
{
System.out.println("additional concern");
//System.out.println("Method Signature: " + jp.getSignature());
}
}
现在创建定义bean的applicationContext.xml文件。
现在,让我们调用实际方法。
package com.javatpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Operation e = (Operation) context.getBean("opBean");
System.out.println("calling msg...");
e.msg();
System.out.println("calling m...");
e.m();
System.out.println("calling k...");
e.k();
}
}
- calling msg...
- additional concern
- msg() method invoked
- calling m...
- additional concern
- m() method invoked
- calling k...
- additional concern
- k() method invoked
如您所见,在调用msg(),m()和k()方法之前,需要打印其他一些问题。
现在,如果您更改切入点表达式,如下所示:
- @Pointcut("execution(* Operation.m*(..))")
现在,在操作类中以m开头的方法将引起更多关注。输出将如下所示:
- calling msg...
- additional concern
- msg() method invoked
- calling m...
- additional concern
- m() method invoked
- calling k...
- k() method invoked
现在您可以看到在调用k()方法之前未打印其他问题。
调用实际的业务逻辑方法后,将应用忠于建议的AspectJ。它可以用来维护日志,安全性,通知等。
在这里,我们假设Operation.java , applicationContext.xml和Test.java文件与@Before示例中给出的文件相同。
创建包含后建议的方面类。
package com.javatpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation{
@Pointcut("execution(* Operation.*(..))")
public void k(){}//pointcut name
@After("k()")//applying pointcut on after advice
public void myadvice(JoinPoint jp)//it is advice (after advice)
{
System.out.println("additional concern");
//System.out.println("Method Signature: " + jp.getSignature());
}
}
- calling msg...
- msg() method invoked
- additional concern
- calling m...
- m() method invoked
- additional concern
- calling k...
- k() method invoked
- additional concern
您可以看到在调用msg(),m()和k()方法之后,还会显示其他问题。
通过在返回建议后使用,我们可以在建议中获得结果。
创建包含业务逻辑的类。
package com.javatpoint;
public class Operation{
public int m(){System.out.println("m() method invoked");return 2;}
public int k(){System.out.println("k() method invoked");return 3;}
}
返回建议后,创建包含的方面类。
package com.javatpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TrackOperation{
@AfterReturning(
pointcut = "execution(* Operation.*(..))",
returning= "result")
public void myadvice(JoinPoint jp,Object result)//it is advice (after returning advice)
{
System.out.println("additional concern");
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Result in advice: "+result);
System.out.println("end of after returning advice...");
}
}
与@Before建议示例中给出的相同
现在,创建调用实际方法的Test类。
package com.javatpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Operation e = (Operation) context.getBean("opBean");
System.out.println("calling m...");
System.out.println(e.m());
System.out.println("calling k...");
System.out.println(e.k());
}
}
- calling m...
- m() method invoked
- additional concern
- Method Signature: int com.javatpoint.Operation.m()
- Result in advice: 2
- end of after returning advice...
- 2
- calling k...
- k() method invoked
- additional concern
- Method Signature: int com.javatpoint.Operation.k()
- Result in advice: 3
- end of after returning advice...
- 3
您可以看到返回值被打印了两次,一次是由TrackOperation类打印的,第二次是由Test类打印的。
围绕建议的AspectJ在调用实际的业务逻辑方法之前和之后都会应用。
在这里,我们假设applicationContext.xml文件与@Before示例中给出的文件相同。
创建一个包含实际业务逻辑的类。
package com.javatpoint;
public class Operation{
public void msg(){System.out.println("msg() is invoked");}
public void display(){System.out.println("display() is invoked");}
}
创建包含建议周围的方面类。
您需要在advice方法中传递PreceedingJoinPoint引用,以便我们可以通过调用progress()方法来进行请求。
package com.javatpoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation
{
@Pointcut("execution(* Operation.*(..))")
public void abcPointcut(){}
@Around("abcPointcut()")
public Object myadvice(ProceedingJoinPoint pjp) throws Throwable
{
System.out.println("Additional Concern Before calling actual method");
Object obj=pjp.proceed();
System.out.println("Additional Concern After calling actual method");
return obj;
}
}
现在,创建调用实际方法的Test类。
package com.javatpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
public static void main(String[] args){
ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml");
Operation op = (Operation) context.getBean("opBean");
op.msg();
op.display();
}
}
- Additional Concern Before calling actual method
- msg() is invoked
- Additional Concern After calling actual method
- Additional Concern Before calling actual method
- display() is invoked
- Additional Concern After calling actual method
您可以看到在调用msg()和display方法之前和之后都会打印出其他问题。
通过使用引发建议后的用法,我们可以在TrackOperation类中print异常。让我们看一下AspectJ AfterThrowing建议的示例。
创建包含业务逻辑的类。
package com.javatpoint;
public class Operation{
public void validate(int age)throws Exception{
if(age<18){
throw new ArithmeticException("Not valid age");
}
else{
System.out.println("Thanks for vote");
}
}
}
在抛出建议后,创建包含的方面类。
在这里,我们还需要传递Throwable引用,以便我们可以在此处拦截异常。
package com.javatpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TrackOperation{
@AfterThrowing(
pointcut = "execution(* Operation.*(..))",
throwing= "error")
public void myadvice(JoinPoint jp,Throwable error)//it is advice
{
System.out.println("additional concern");
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Exception is: "+error);
System.out.println("end of after throwing advice...");
}
}
与@Before建议示例中给出的相同
现在,创建调用实际方法的Test类。
package com.javatpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Operation op = (Operation) context.getBean("opBean");
System.out.println("calling validate...");
try{
op.validate(19);
}catch(Exception e){System.out.println(e);}
System.out.println("calling validate again...");
try{
op.validate(11);
}catch(Exception e){System.out.println(e);}
}
}
- calling validate...
- Thanks for vote
- calling validate again...
- additional concern
- Method Signature: void com.javatpoint.Operation.validate(int)
- Exception is: java.lang.ArithmeticException: Not valid age
- end of after throwing advice...
- java.lang.ArithmeticException: Not valid age