Spring AOP兩種實現方式


一. AOP 概念:  
  Spring AOP 即Aspect Oriented Programming(面向切面編程), 實現方式分為兩種:
  1. 注解(Annotation)
  2. 配置(Configure)
二. 應用場景:
  1. 權限管理;
  2. 表單驗證;
  3. 事務管理;
  4. 信息過濾;
  5. 攔截器;
  6. 過濾器;
  7. 日志等等;

三. AOP實現:
  1. 基於Annotation的實現  
package com.myframework.xj.security.service;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.myframework.xj.credit.CreditException;import com.myframework.xj.security.entity.CheckDetails;
import com.myframework.xj.security.entity.User;

/**
 * 基於注解的AOP實現核查扣款功能
 * @author lvm
 *
 */
@Component
@Aspect
public class CheckServiceAspect {
    
    private static final Logger logger = LoggerFactory.getLogger(CheckServiceAspect.class);
    
    @Autowired
    private CheckDetailsService checkDetailsService;//配置切入點,該方法無方法體,主要為方便同類中其他方法使用此處配置的切入點
    @Pointcut("execution(* com.myframework.xj.security.service.*..(..))")
    public void aspect(){}

    /**
     * 實現代碼
     * @param call
     * @return
     * @throws Throwable
     */
    @Around("aspect()")
    public Object aroundCheck(ProceedingJoinPoint call) throws Throwable {
        logger.info("CheckServiceAspect aroundCheck begin...");
        
        Object[] args = call.getArgs();
        //1.當前登錄人
        if(args[0] == null || !(args[0] instanceof User))
            throw new CreditException("當前登錄人不能為空");
        User user = (User)(args[0]);
        
        //2.查詢金額
        CheckDetails details = new CheckDetails();
        if(user.getFund() == null || user.getFund().compareTo(details.getPayment()) <0)
            throw new CreditException("當前登錄人賬戶余額不夠");
        try {
            return call.proceed();
        } finally {
            details.setCreatedBy(user);
            checkDetailsService.save(details);
            logger.info("CheckServiceAspect aroundCheck end...");
        }
    }
    
}
  基於Annotationd的實現需要保證可以被配置文件掃描到  
<!-- 激活組件掃描功能,在包com.myframework.xj.security.service及其子包下面自動掃描通過注解配置的組件 -->
<context:component-scan base-package="com.myframework.xj.security.service"/>
<!-- 激活自動代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

  2. 基於Configure的實現
  Java實現代碼如下:  
package com.myframework.xj.security.service;

import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.myframework.xj.credit.CreditException;
import com.myframework.xj.security.entity.CheckDetails;
import com.myframework.xj.security.entity.User;

/**
 * 根據配置文件實現AOP實現扣款功能
 * @author lvm
 *
 */
public class Aspect {
    
    private static final Logger logger = LoggerFactory.getLogger(CheckAspect.class);
    
    private CheckDetailsService checkDetailsService;    
    
    public void setCheckDetailsService(CheckDetailsService checkDetailsService) {
        this.checkDetailsService = checkDetailsService;
    }
    
    /**
     * 實現代碼
     * @param call
     * @return
     * @throws Throwable
     */
    public Object aroundCheck(ProceedingJoinPoint call) throws Throwable {
        
        logger.info("Aspect aroundCheck begin...");
        
        Object[] args = call.getArgs();
        //1.當前登錄人
        if(args[0] == null || !(args[0] instanceof User))
            throw new CreditException("當前登錄人不能為空");
        User user = (User)(args[0]);
        
        //2.查詢金額
        CheckDetails details = new CheckDetails();
        if(user.getFund() == null || user.getFund().compareTo(details.getPayment()) <0)
            throw new CreditException("當前登錄人賬戶余額不夠");
        try {
            return call.proceed();
        } finally {
            details.setCreatedBy(user);
            checkDetailsService.save(details);
            logger.info("Aspect aroundCheck end...");
        }
    }
}

  配置文件如下:  
<bean id="checkDetailsServiceImpl" class="com.myframework.xj.security.service.CheckDetailsServiceImpl"/>
<bean id="reportServiceImpl" class="com.myframework.xj.credit.service.ReportServiceImpl"/>
<bean id="checkAspectExecutor" class="com.myframework.xj.security.service.CheckAspect">
    <property name="checkDetailsService" ref="checkDetailsServiceImpl"/>
    <property name="reportService" ref="reportServiceImpl"/>
</bean>
<aop:config>
    <aop:aspect id="checkAspect" ref="checkAspectExecutor">
        <aop:pointcut id="checkPointcut" expression="execution(* com.myframework.xj.security.service.CheckDetailsServiceImpl.check*(..))"/>
        <aop:around pointcut-ref="checkPointcut" method="aroundCheck" />
    </aop:aspect>
</aop:config>

四. Annotation和Configure實現比較
  配置麻煩點 但是可讀性好點 
  注解方便



 
         
         
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM