Spring中的AOP有关概念

时间:2021-03-30 06:15:59

AOP中的概念

 

Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.(类)

joinpoint(连接点):所谓连接点是指那些被拦截到的点。在Spring AOP中一个连接点代表一个方法的执行(方法)

Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.(范围)

Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(具体实现)

Target(目标对象):代理的目标对象 (目标对象)

Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.

 

Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

 

 


使用Spring进行面向切面(AOP)编程


要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:
<beans xmlns="
http://www.springframework.org/schema/beans"
       xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="
http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
</beans>

 

 

Spring提供了两种切面声明方式

1.基于XML配置方式声明切面。
2.基于注解方式声明切面。

 

 


基于注解方式声明切面

1、启用注解 <aop:aspectj-autoproxy/>
2、采用Aspect定义切面
3、在Aspect定义Pointcut和Advice
4、Aspect类和目标对象配置到Ioc容器中,目标对象要实现接口

注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点
即Advice中通过方法名引用这个切人点


@Aspect
public class LogPrint {
   // 定义Pointcut,Pointcut的名称就是anyMethod,此方法不能有返回值和参数,该方法只是

   //一个 标识Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint)
   @Pointcut("execution(* cn.itcast.service..*.*(..))")
   private void anyMethod() {}//声明一个切入点

 
   // 定义Advice,标识在那个切入点何处织入此方法

   @Before("anyMethod() && args(userName)")
    //前置通知,拦截Pointcut指定范围的方法并且方法的参数只有1个String类型的参

    // ,userName为方法传过来的参数
   public void doAccessCheck(String userName) {} 

 


   @AfterReturning(pointcut="anyMethod()",returning="revalue")
   //后置通知,拦截Pointcut指定的范围的方法并且方法的返回值是1个String类型的,

   //revalue   为方法传过来的返回值

    public void doReturnCheck(String revalue) {}

 


    @AfterThrowing(pointcut="anyMethod()", throwing="ex")
    //例外通知,
ex为抛出异常的信息
    public void doExceptionAction(Exception ex) {}

 

 


   @After("anyMethod()")
   //最终通知
   public void doReleaseAction() {}

 


   @Around("anyMethod()")
   //环绕通知 此方法的除方法名和方法参数名可变,其他默认的。只有返回pjp.proceed(),

   //拦截到的方法才会执行
   public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入方法");
        return pjp.proceed();
        System.out.println("结束方法");
   }

 


基于基于XML配置方式声明切面

public class LogPrint {
 public void doAccessCheck() {}定义前置通知
 public void doReturnCheck() {}定义后置通知
 public void doExceptionAction() {}定义例外通知
 public void doReleaseAction() {}定义最终通知
 public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
  return pjp.proceed();环绕通知
 }
}

<bean id="orderservice" class="cn.itcast.service.OrderServiceBean"/>
<bean id="log" class="cn.itcast.service.LogPrint"/>
<aop:config>
  <aop:aspect id="myaop" ref="log">
   <aop:pointcut id="mycut" expression="execution(* cn.itcast.service..*.*(..))"/>
   <aop:before pointcut-ref="mycut" method="doAccessCheck"/>
   <aop:after-returning pointcut-ref="mycut" method="doReturnCheck "/>
   <aop:after-throwing pointcut-ref="mycut" method="doExceptionAction"/>
   <aop:after pointcut-ref="mycut" method=“doReleaseAction"/>
   <aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
  </aop:aspect>
</aop:config>

execution表达式的例子。


任意公共方法的执行:
execution(public * *(..))

任何一个名字以“set”开始的方法的执行:
execution(* set*(..))

AccountService接口定义的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))

在service包中定义的任意方法的执行:
execution(* com.xyz.service.*.*(..))

在service包或其子包中定义的任意方法的执行:
execution(* com.xyz.service..*.*(..))

 

Aspect默认情况下不用实现接口,但对于目标对象,在默认情况下必须实现接口
如果没有实现接口必须引入CGLIB库.

 

我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得拦截到方法的参数值、方法名等等

 public class SecurityHandler {
 
 private void checkSecurity(JoinPoint joinPoint) {
  Object[] args = joinPoint.getArgs(); //取得方法参数
  for (int i=0; i<args.length; i++) {
   System.out.println(args[i]);
  }
  System.out.println(joinPoint.getSignature().getName()); //取得方法名称
  System.out.println("----------checkSecurity()---------------");
 }
 
}