Spring 框架AOP技术

一、AOP技术概念

        面向切面编程[底层就是动态代理]指程序在运行期间动态的将某段代码切入到指定方法位置进行运行的编程方式。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

二、Spring AOP 相关术语

       1、切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现;

       2、连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行;

      3、通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作通知有各种类型,其中包括"around"、 "before”

和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型,并维护一个以连接点为中心 的拦截器链;

      4、切入点(Pointcut):定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。


三、通知Advice类型

         1、前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)  
       2、返回后通知(@AfterReturning):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回

       3、抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知

       4、后通知(@After):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)

       5、环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可

以在方法调用 * 前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行

四、代码示例

    加入依赖


        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>

1、定义切面织入点注解

@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CollectEnable {
      boolean  isCollect()  default false;
}

 2、定义切面

@Aspect
@Component
public class CollectAspect {

 private final  static Logger  LOGGER= LoggerFactory.getLogger(CollectAspect.class);

 @Value("${collect.canable}")
 private boolean isConfig;

    /**
     * 判断是否有注解
     * @param  joinPoint  连接点
     */
  private   CollectEnable  getCollectAnnotation(JoinPoint  joinPoint){
      Signature signature = joinPoint.getSignature();
      MethodSignature methodSignature= (MethodSignature) signature;
      Method  method=methodSignature.getMethod();
      if(method!=null){
          return method.getAnnotation(CollectEnable.class);
      }
      return null;
  }

 /**
  *配置切面的织入点
  */
 @Pointcut("@annotation(com.fce.mycat.submeter.anotation.CollectEnable)")
 public void collectPointCut(){}


 /**
  * 在切点方法之前执行
  * @param joinPoint
  */
 @Before("collectPointCut()")
 public   void  doBefore(JoinPoint  joinPoint){
     CollectEnable collectAnnotation = getCollectAnnotation(joinPoint);
     if(collectAnnotation!=null){
         LOGGER.info("CollectAspect-->doBefore-------前置织入");
     }
 }

 @After("collectPointCut()")
 public  void doAfter(JoinPoint  joinPoint){
     CollectEnable collectAnnotation = getCollectAnnotation(joinPoint);
     if(collectAnnotation!=null){
         LOGGER.info("CollectAspect-->doAfter-------后置织入");
     }
 }

 /**
  * 环绕增强,控制包裹代码是否执行
  * @param joinPoint
  */
 @Around("collectPointCut()")
 public  void  doAround(ProceedingJoinPoint  joinPoint){
     CollectEnable collectAnnotation = getCollectAnnotation(joinPoint);
     boolean collect = collectAnnotation.isCollect();
     if(collect&&isConfig){
         LOGGER.info("CollectAspect-->doAround----开启采集任务");
         try {
             joinPoint.proceed();
         } catch (Throwable throwable) {
             throwable.printStackTrace();
         }
     }else{
         LOGGER.info("CollectAspect-->doAround----禁止执行采集");
     }
 }

}

 3、在切点上使用增强

@Service
public class CollectService {

    private final static Logger LOGGER= LoggerFactory.getLogger(CollectService.class);

    @CollectEnable(isCollect = true)
    public void   collect360(){
        LOGGER.info("CollectService---->collect360()-------开始采集了");
    }

    @CollectEnable
    public  void  collectHuaWei(){
        LOGGER.info("CollectService---->collectHuaWei()----开始采集了");
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值