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实现比较
  配置麻烦点 但是可读性好点 
  注解方便




原文地址:https://www.cnblogs.com/xx0405/p/5497672.html