springAOP的实现方式

103 阅读2分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

前言

基于上篇介绍玩AOP的相关概念以及通知类型,我们继续了解AOP的几种使用方法.

  • 经典的基于代理的AOP
  • @AspectJ注解驱动的切面
  • 纯POJO切面(纯粹通过aop:fonfig标签配置)
  • 注入式AspectJ切面

AOP常用的实现方式有两种,

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

2、是采用注解的方式来实现(基于@AspectJ注解驱动的切面)。

具体使用方式

1.经典的基于代理的AOP实现,大致步骤为:配置文件中配置pointcut, 在java中用编写实际的aspect 类, 针对对切入点进行相关的业务处理。
JDK动态代理:动态代理是在运行时动态的生成一个代理类,在其中插入横切逻辑,在调用方法时不调用本来类的方法,转而调用代理类的方法

业务接口:

public interface IUserService {
   
    public String findUser();
  
}
public class UserServiceImpl implements IUserService{
private String name;
    public void setName(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }
    public String findUser(){
        System.out.println("============执行业务方法findUser,查找的用户是:"+name+"=============");
        return name;
    }
  
}

切面类:

public class AopAspect {
 
    public void doBefore(JoinPoint jp){
        System.out.println("===========执行前置通知============");
    }
​
    public void doAfterReturning(JoinPoint jp,String result){
        System.out.println("===========执行后置通知============");
        System.out.println("返回值result==================="+result);
    }
​
    public void doAfter(JoinPoint jp){
        System.out.println("===========执行最终通知============");
    }
​
    public void doAfterThrowing(JoinPoint jp,Exception ex){
        System.out.println("===========执行异常通知============");
    }
​
​
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
 System.out.println("======执行环绕通知开始=========");
         Object result=pjp.proceed();
        System.out.println("======执行环绕通知结束=========");
        return result;
    }
}

Spring配置:

 <!-- 声明一个业务类 -->
    <bean id="userManager" class="com.spring.service.impl.UserManagerServiceImpl">
        <property name="name" value="lixiaoxi"></property>
    </bean>  
    <!-- 声明通知类 -->
    <bean id="aspectBean" class="com.spring.aop.AopAspect" />
    <aop:config>
     <aop:aspect ref="aspectBean">
        <aop:pointcut id="pointcut" expression="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))"/>
        <aop:before method="doBefore" pointcut-ref="pointcut"/> 
        <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result"/>
        <aop:after method="doAfter" pointcut-ref="pointcut" /> 
        <aop:around method="doAround" pointcut-ref="pointcut"/> 
        <aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="ex"/>
      </aop:aspect>
   </aop:config>

二、使用注解配置AOP

采用注解来做aop, 主要是将写在spring 配置文件中的连接点写到注解里面。

业务接口和业务实现与上边一样,具体切面类如下:

@Aspect
public class AopAspectJ {
 
    public static final String EDP="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))";
   
    @Before(EDP)
    public void doBefore(JoinPoint jp){
        System.out.println("=========执行前置通知==========");
    }
  
    @AfterReturning(value=EDP,returning="result")
    public void doAfterReturning(JoinPoint jp,String result){
        System.out.println("===========执行后置通知============");
    }
   
    @After(value=EDP)
    public void doAfter(JoinPoint jp){
        System.out.println("===========执行最终通知============");
    }
​
    @Around(EDP)
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("======执行环绕通知开始=========");
         Object result=pjp.proceed();
        System.out.println("======执行环绕通知结束=========");
        return result;
    }
    /**
     * 在目标方法非正常执行完成, 抛出异常的时候会走此方法
     * @param jp
     * @param ex
     */
    @AfterThrowing(value=EDP,throwing="ex")
    public void doAfterThrowing(JoinPoint jp,Exception ex) {
        System.out.println("===========执行异常通知============");
    }
}

spring的配置:

 <!-- 声明spring对@AspectJ的支持 -->
    <aop:aspectj-autoproxy/>    
    <!-- 声明一个业务类 -->
    <bean id="userManager" class="com.spring.service.impl.UserManagerServiceImpl">
        <property name="name" value="lixiaoxi"></property>
    </bean>   
     <!-- 声明通知类 -->
    <bean id="aspectBean" class="com.spring.aop.AopAspectJ" />

\