Spring AOP三种表现形式

  • Spring AOP三种表现形式

spring AOP 是spring框架两大核心思想之一,aop即是面向切面编程,意在解决程序中系统级别的附加在类尤其是方法上的功能的问题,aop的核心是代理模式,实现aop在spring中四种方式,以下是spring自身实现、依赖aspectj实现,和基于aspecet的注解实现。

1.spring提供的aop实现方式:基于XML配置和实现接口的类联合应用:

   
   <bean id="orderServiceBean" class="com.apesource.dao.Impl.OrderServiceImpl"/>
   <bean id="userServiceBean" class="com.apesource.dao.Impl.UserServiceImpl"/>

   
   <bean id="logAdviceBean" class="com.apesource.dao.advice.LogAdvice"/>
   <bean id="gexAdvice" class="com.apesource.dao.advice.GTXAdvice"/>

   
   <bean id="createMethodPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
       <property name="pattern" value=".*User.*"/>
   bean>

   
   <bean id="pointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
       <property name="advice" ref="gexAdvice"/>
       <property name="pointcut" ref="createMethodPointcut"/>
   bean>

   <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
       <property name="beanNames">
           <list>
               <value>*ServiceBeanvalue>
           list>
       property>

       <property name="interceptorNames">
           <list>
               <value>logAdviceBeanvalue>
             	<value>pointcutAdvisorvalue>
           list>
       property>
   bean>
// 拦截器
public class GTXAdvice implements MethodInterceptor {
   @Override
   public Object invoke(MethodInvocation methodInvocation) throws Throwable {
       System.out.println("方法名称:"  + methodInvocation.getMethod().getName());
       System.out.println("性能检测中......");
       System.out.println("方法执行前....");

       long beginTime = System.currentTimeMillis();
       Object result = methodInvocation.proceed();
       long endTime = System.currentTimeMillis();

       System.out.println("方法执行时间:"+(endTime-beginTime)+"毫秒");
       System.out.println("方法执行后.....");
       return result;
   }
}
// 通知类
public class LogAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
   @Override
   public void afterReturning(Object result, Method method, Object[] objects, Object target) throws Throwable {
       System.out.println("通知:" + target.getClass().getName() + "的" + method.getName()+ "方法在" + new Date() + "执行完毕" + "其返回值:" + result);
   }

   @Override
   public void before(Method method, Object[] objects, Object target) throws Throwable {
       System.out.println("通知:" + target.getClass().getName() + "的" + method.getName() + "方法在" + new Date() + "开始执行");

   }
}

2.aspect提供的aop实现:基于XML配置和aspect配置类组成:


   
   <bean id="recordServiceBean" class="com.apesource.dao.Impl.RecordServiceImpl"/>
   
   <bean id="logAspectBean" class="com.apesource.dao.advice.LogAspect"/>
   
   <aop:config>
       
       <aop:aspect ref="logAspectBean">
           
           <aop:pointcut id="recordPointcut" expression="execution(* com.apesource.dao.Impl.*.create*(..))"/>
           
           <aop:before method="doBeforeAdvice" pointcut-ref="recordPointcut"/>
           
           <aop:after method="doAfterAdvice" pointcut-ref="recordPointcut"/>
           
           <aop:after-returning method="doAfterReturnAdvice" returning="object" pointcut-ref="recordPointcut"/>
           
           <aop:after-throwing method="throwingAdvice" pointcut-ref="recordPointcut" throwing="ex"/>
           
           <aop:around method="aroundAdvice" pointcut-ref="recordPointcut"/>

       aop:aspect>
   aop:config>
// aspect配置类
public class LogAspect {
   // 前置通知

   public  void  doBeforeAdvice(JoinPoint joinPoint){
       System.out.println("使用aspectjrt中......");
       System.out.println("前置开始执行");
       System.out.println(joinPoint.getTarget());
       System.out.println(joinPoint.getArgs().getClass().getName());
       System.out.println("前置执行完毕");
   }
   // 后置通知
   public void doAfterAdvice(JoinPoint joinPoint){
       System.out.println("后置开始执行");
       System.out.println(joinPoint.getTarget());
       System.out.println(joinPoint.getArgs().getClass().getName());
       System.out.println("后置执行完毕");
   }
   // 带有返回值后置通知,如果出现执行取消
   public void doAfterReturnAdvice(JoinPoint joinPoint,Object object){
       System.out.println("后置带有返回值开始执行");
       System.out.println(joinPoint.getTarget());
       System.out.println(joinPoint.getArgs().getClass().getName());
       System.out.println("返回值:"+object);
       System.out.println("后置带有返回值执行完毕");
   }

   // 异常通知:出现异常,执行该通知
   public void throwingAdvice(JoinPoint joinPoint,Exception ex){
       System.out.println("异常通知开始执行");
       System.out.println(joinPoint.getTarget());
       System.out.println(joinPoint.getArgs().getClass().getName());
       System.out.println("返回值:"+ex.getMessage());
       System.out.println("异常通知执行完毕");
   }

   // 环绕通知
   public  Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
       System.out.println("************环绕通知前***********");
       Object object = joinPoint.proceed();
       System.out.println("************环绕通知后**************");
       return object;
   }

}

3.aspect使用注解实现:基于XML自动配置和切面类配置组合:


<context:component-scan base-package="com.apesource"/>
<aop:aspectj-autoproxy/>
// 通知类注解配置
// 加入spring容器
// 配置为切面
@Component
@Aspect
public class LogAspectAnnotationAdvice {
       // 定义切入点
       private static final String POINTCUT_EXPRESSION = "execution(* com.apesource.dao.Impl.*.create*(..) )";

       /**
        * 前置通知
        */
       @Before(POINTCUT_EXPRESSION)
       public void beforeAdvice(JoinPoint joinpoint){
           System.out.println("==========【使用AspectJ实现前置通知】开始==================");
           System.out.println("目标对象:" + joinpoint.getTarget());
           System.out.println("目标方法:" + joinpoint.getSignature().getName());
           System.out.println("参数列表:" + joinpoint.getArgs());
           System.out.println("==========【使用AspectJ实现前置通知】结束==================");
       }

       /**
        * 后置通知:方法正常执行后,有返回值,执行该后置通知;如果该方法执行出现异常,则不执行该后置通知
        */
       @AfterReturning(value = POINTCUT_EXPRESSION,returning = "returnVal")
       public void afterReturningAdvice(JoinPoint joinpoint,Object returnVal){
           System.out.println("==========【使用AspectJ实现后置通知】开始==================");
           System.out.println("目标对象:" + joinpoint.getTarget());
           System.out.println("目标方法:" + joinpoint.getSignature().getName());
           System.out.println("参数列表:" + joinpoint.getArgs());
           System.out.println("返回值:" + returnVal);
           System.out.println("==========【使用AspectJ实现后置通知】结束==================");
       }

       /**
        * 后置通知
        */
       @After(POINTCUT_EXPRESSION)
       public void afterAdvice(JoinPoint joinpoint){
           System.out.println("==========【使用AspectJ实现后置通知】开始==================");
           System.out.println("目标对象:" + joinpoint.getTarget());
           System.out.println("目标方法:" + joinpoint.getSignature().getName());
           System.out.println("参数列表:" + joinpoint.getArgs());
           System.out.println("==========【使用AspectJ实现后置通知】结束==================");
       }

       /**
        * 异常通知:方法出现异常时,执行该通知
        * @param joinpoint
        * @param ex
        */
       @AfterThrowing(value = POINTCUT_EXPRESSION,throwing = "ex")
       public void throwingAdvice(JoinPoint joinpoint, Exception ex){
           System.out.println("==========【使用AspectJ实现异常通知】开始==================");
           System.out.println("目标对象:" + joinpoint.getTarget());
           System.out.println("目标方法:" + joinpoint.getSignature().getName());
           System.out.println("出现异常:" + ex.getMessage());
           System.out.println("==========【使用AspectJ实现异常通知】结束==================");
       }

       /**
        * 环绕通知
        */
       @Around(POINTCUT_EXPRESSION)
       public Object aroundAdvice(ProceedingJoinPoint joinpoint) throws Throwable {

           System.out.println("#########$环绕通知的前置部分$###############");
           Object returnVal = joinpoint.proceed();
           System.out.println("#########$环绕通知的后置部分$###############");

           return returnVal;
       }
   }

你可能感兴趣的:(Spring,spring,aop)