Spring系列中的AOP实现的两种方式

一、AOP实现的两种方式

(1)采用声明的方式来实现(基于XML)

(2)是采用注解的方式来实现(基于AspectJ)。

二、AOP的一些重要概念

(1)Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行 。

(2)Pointcut(切点):说的通俗点,spring中AOP的切点就是指一些方法的集合,而这些方法是需要被增强、被代理的。一般都                                          是按照一定的约定规则来表示的,如正则表达式等。切点是由一类连接点组成。 
(3)Advice(通知):还是说的通俗点,就是在指定切点上要干些什么。 
(4)Advisor(通知器):其实就是切点和通知的结合 。

三、AOP实现的实例

1.基于XML配置的Spring AOP(采用声明的方式实现(在XML文件中配置),大致步骤为:配置文件中配置pointcut, 在java中用编写实际的aspect 类, 针对对切入点进行相关的业务处理。

业务接口

public interface IUserManagerService {
   
    List findUser();
    
    void addUser(User user);
}

业务实现

public class UserManagerServiceImpl implements IUserManagerService{
    @Autowired
    private UserManagerMapper userManagerMapper;

    public  List findUser(){
        return userManagerMapper.findUser();
    }
    
    public void addUser(User user){
        return userManagerMapper.addUser(user);
    }
}

 

切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class AopAspect {
    
    /**
     * 前置通知:目标方法调用之前执行的代码
      * @param jp
     */
    public void doBefore(JoinPoint jp){
        System.out.println("===========执行前置通知============");
    }
    
    /**
     * 后置返回通知:目标方法正常结束后执行的代码
      * 返回通知是可以访问到目标方法的返回值的
      * @param jp
     * @param result
     */
    public void doAfterReturning(JoinPoint jp,String result){
        System.out.println("===========执行后置通知============");
        System.out.println("返回值result==================="+result);
    }
    
    /**
     * 最终通知:目标方法调用之后执行的代码(无论目标方法是否出现异常均执行)
      * 因为方法可能会出现异常,所以不能返回方法的返回值
      * @param jp
     */
    public void doAfter(JoinPoint jp){
        System.out.println("===========执行最终通知============");
    }
    
    /**
     * 
     * 异常通知:目标方法抛出异常时执行的代码
      * 可以访问到异常对象
      * @param jp
     * @param ex
     */
    public void doAfterThrowing(JoinPoint jp,Exception ex){
        System.out.println("===========执行异常通知============");
    }
    
    /**
     * 环绕通知:目标方法调用前后执行的代码,可以在方法调用前后完成自定义的行为。
      * 包围一个连接点(join point)的通知。它会在切入点方法执行前执行同时方法结束也会执行对应的部分。
      * 主要是调用proceed()方法来执行切入点方法,来作为环绕通知前后方法的分水岭。
      * 
     * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
      * 而且环绕通知必须有返回值,返回值即为目标方法的返回值
      * @param pjp
     * @return
     * @throws Throwable
     */
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("======执行环绕通知开始=========");
         // 调用方法的参数
        Object[] args = pjp.getArgs();
        // 调用的方法名
        String method = pjp.getSignature().getName();
        // 获取目标对象
        Object target = pjp.getTarget();
        // 执行完方法的返回值
        // 调用proceed()方法,就会触发切入点方法执行
        Object result=pjp.proceed();
        System.out.println("输出,方法名:" + method + ";目标对象:" + target + ";返回值:" + result);
        System.out.println("======执行环绕通知结束=========");
        return result;
    }
}

Spring的XML配置



    
    
    
        
      
    
     
    

    
     
        
        
         
        
         
         
        
      
   

测试类

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.service.IUserManagerService;

public class TestAop {

    public static void main(String[] args) throws Exception{
        
        ApplicationContext act =  new ClassPathXmlApplicationContext("applicationContext3.xml");
         IUserManagerService userManager = (IUserManagerService)act.getBean("userManager");
         userManager.findUser();
         System.out.println("\n");
         userManager.addUser();
    }
}

测试结果

Spring系列中的AOP实现的两种方式_第1张图片

2.使用注解实现AOP(采用注解来做aop, 主要是将写在spring 配置文件中的连接点写到注解里面。业务接口和业务实现与上边一样,具体切面类如下:

package com.spring.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopAspectJ {
    
    /**  
     * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的  
     */  
    public static final String EDP="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))";
    
    /**
     * 切面的前置方法 即方法执行前拦截到的方法
      * 在目标方法执行之前的通知
      * @param jp
     */
    @Before(EDP)
    public void doBefore(JoinPoint jp){
        
        System.out.println("=========执行前置通知==========");
    }
    
    
    /**
     * 在方法正常执行通过之后执行的通知叫做返回通知
      * 可以返回到方法的返回值 在注解后加入returning 
     * @param jp
     * @param result
     */
    @AfterReturning(value=EDP,returning="result")
    public void doAfterReturning(JoinPoint jp,String result){
        System.out.println("===========执行后置通知============");
    }
    
    /**
     * 最终通知:目标方法调用之后执行的通知(无论目标方法是否出现异常均执行)
      * @param jp
     */
    @After(value=EDP)
    public void doAfter(JoinPoint jp){
        System.out.println("===========执行最终通知============");
    }
    
    /**
     * 环绕通知:目标方法调用前后执行的通知,可以在方法调用前后完成自定义的行为。
      * @param pjp
     * @return
     * @throws Throwable
     */
    @Around(EDP)
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable{

        System.out.println("======执行环绕通知开始=========");
        // 调用方法的参数
        Object[] args = pjp.getArgs();
        // 调用的方法名
        String method = pjp.getSignature().getName();
        // 获取目标对象
        Object target = pjp.getTarget();
        // 执行完方法的返回值
        // 调用proceed()方法,就会触发切入点方法执行
        Object result=pjp.proceed();
        System.out.println("输出,方法名:" + method + ";目标对象:" + target + ";返回值:" + result);
        System.out.println("======执行环绕通知结束=========");
        return result;
    }
    
    /**
     * 在目标方法非正常执行完成, 抛出异常的时候会走此方法
      * @param jp
     * @param ex
     */
    @AfterThrowing(value=EDP,throwing="ex")
    public void doAfterThrowing(JoinPoint jp,Exception ex) {
        System.out.println("===========执行异常通知============");
    }
}

配置类



    
    
        
    
    
    
        
       
    
     
    

测试结果相同

你可能感兴趣的:(SSM框架及相关技术)