• Spring Aop实现方式总结


    前面两个文章介绍了Aop及其相关重要概念,下面主要用代码的方式介绍下实现Spring Aop的几种方式

    1. 基于注解实现Spring Aop

    业务类接口

    package cn.test.business;
    
    public interface Work {
    
    	public void doWork(String userName);
    }
    

    业务类实现

    package cn.test.business;
    
    public class Worker implements Work{
    
    	@Override
    	public void doWork(String userName) {
    		System.out.println(userName + " is working !");
    	}
    }
    

    注解实现切面类

    @Aspect
    public class AopAnnotationTest {  
    	
        @Pointcut("execution(* cn.test.business.*.*(..))")  
        private void anyMethod(){}//定义一个切入点 
    	
        @Before("anyMethod() && args(name)")  
        public void doBefore(String name){  
            System.out.println("doBefore...");  
        }  
        
        @AfterReturning("anyMethod()")
        public void doAfterReturning(){
        	System.out.println("doAfterReturning...");
        }
        
        @After("anyMethod()")
        public void doAfter(){
        	System.out.println("doAfter...");
        }
        
        @Around("anyMethod()")
        public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
        	System.out.println("begin doAround...");
        	Object object = joinPoint.proceed();
        	System.out.println("after doAround...");
        	return object;
        }
        
        @AfterThrowing("anyMethod()")
        public void doThrow(){
        	System.out.println("意外通知");
        }
    }  

    spring配置文件:spring-aop.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
     
    		  <bean id="work" class="cn.test.business.Worker"></bean>
    		  
    		  <!-- aop注解 实现 -->
    		  <aop:aspectj-autoproxy/>
     		  <bean id="anno-beforeadvice" class="cn.test.aop.advice.annoation.impl.AopAnnotationTest"/>	
    		  
    		  <!-- 实现相应的Advice方法实现aop -->
              <!-- <bean id="logBeforeAdvice" class="cn.test.aop.advice.inteface.impl.LogBeforeAdvice"></bean>
              <bean id="logAfterReturnAdvice" class="cn.test.aop.advice.inteface.impl.LogAfterReturnAdvice"></bean>
              <bean id="logExceptionAdvice" class="cn.test.aop.advice.inteface.impl.LogExceptionAdvice"></bean>
     		  <bean id="logAroundAdvice" class="cn.test.aop.advice.inteface.impl.LogAroundAdvice"></bean>
     
    		  <aop:config>
                    <aop:pointcut id="pointcut" expression="execution(* cn.test.business.*.*(..))" />
                    <aop:advisor advice-ref="logBeforeAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logAfterReturnAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logAroundAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logExceptionAdvice" pointcut-ref="pointcut"/>
              </aop:config>    -->  
              
              <!-- 定义一个切面类 -->
              <!-- <bean id="logAspect" class="cn.test.aop.advice.defineAspectClass.impl.TestAspect"></bean>
              <aop:config>
                      <aop:pointcut id="pointcut" expression="execution(* cn.test.business.*.*(..))" />
                      <aop:aspect id="aspect" ref="logAspect">
                              <aop:before pointcut-ref="pointcut" method="doBefore"/>
                              <aop:after-returning pointcut-ref="pointcut" method="afterReturning" returning="retValue"/>
                              <aop:after-throwing pointcut-ref="pointcut" method="doThrowing" throwing="ex"/>
                              <aop:after pointcut-ref="pointcut" method="doAfter"/>
                              <aop:around pointcut-ref="pointcut" method="doAround"/>
                     </aop:aspect>
              </aop:config> -->
    </beans>

    测试类:

    package cn.test.aop.test;
    
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
    
    import cn.test.business.Work;
    
    
    @ContextConfiguration(
    	locations={
    		"classpath:/spring-aop.xml"
    	}
    )
    public class SpringAopTest extends AbstractJUnit4SpringContextTests{
    
    	@Autowired
    	private Work work;
    	
    	@Test
    	public void aopTest(){
    		work.doWork("张三");
    	}
    }
    

    测试结果:

    begin doAround...
    doBefore...
    张三 is working !
    after doAround...
    doAfter...
    doAfterReturning...

    2. 实现Adivce接口的方式实现Spring Aop

    定义前置通知

    public class LogBeforeAdvice  implements MethodBeforeAdvice {
    
    	@Override
    	public void before(Method method, Object[] args, Object target)
    			throws Throwable {
    		System.out.println(args[0] + "开始工作!");
    	}
    }

    定义环绕通知

    public class LogAroundAdvice implements MethodInterceptor{
    
    	@Override
    	public Object invoke(MethodInvocation arg0) throws Throwable {
    		System.out.println(arg0.getArguments()[0] + " 工作中,请勿打扰...");
            Object obj = arg0.proceed();
            System.out.println(arg0.getArguments()[0] + " 工作完成...");
            return obj;
    	}
    }

    定义返回后通知

    public class LogAfterReturnAdvice implements AfterReturningAdvice{
    
    	@Override
    	public void afterReturning(Object returnValue, Method method,
    			Object[] args, Object target) throws Throwable {
    		System.out.println(args[0] + "完成工作");
    	}
    }

    定义抛出异常后通知

    public class LogExceptionAdvice implements ThrowsAdvice{
    
    	public void afterThrowing(Method method, Object[] parameters, Object target, Exception ex){
            System.out.println(parameters[0] + " 工作中出现异常... ");
        }
    }

    spring配置文件:只需要把上面的配置文件中第二部分打开即可。

    <!-- 实现相应的Advice方法实现aop -->
              <bean id="logBeforeAdvice" class="cn.test.aop.advice.inteface.impl.LogBeforeAdvice"></bean>
              <bean id="logAfterReturnAdvice" class="cn.test.aop.advice.inteface.impl.LogAfterReturnAdvice"></bean>
              <bean id="logExceptionAdvice" class="cn.test.aop.advice.inteface.impl.LogExceptionAdvice"></bean>
     		  <bean id="logAroundAdvice" class="cn.test.aop.advice.inteface.impl.LogAroundAdvice"></bean>
     
    		  <aop:config>
                    <aop:pointcut id="pointcut" expression="execution(* cn.test.business.*.*(..))" />
                    <aop:advisor advice-ref="logBeforeAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logAfterReturnAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logAroundAdvice" pointcut-ref="pointcut"/>
                    <aop:advisor advice-ref="logExceptionAdvice" pointcut-ref="pointcut"/>
              </aop:config> 


    3. 定义切面类的方式实现Spring Aop

    切面类

    public class TestAspect {
    
        public void doAfter(JoinPoint jp) {
        	System.out.println(jp.getArgs()[0] + " 回家...");
        }
    
        public void afterReturning (JoinPoint joinPoint, Object retValue) {
            System.out.println(joinPoint.getArgs()[0] + " 结束工作...");
        }
        
        public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        	long time = System.currentTimeMillis();
            Object retVal = pjp.proceed();
            time = System.currentTimeMillis() - time;
            System.out.println(pjp.getArgs()[0] +" 工作时间: " + time + " ms");
            return retVal;
        }
    
        public void doBefore(JoinPoint jp) {
        	System.out.println(jp.getArgs()[0] + " 开始工作...");
        }
    
        public void doThrowing(JoinPoint jp, Throwable ex) {
        	System.out.println(jp.getArgs()[0] + " 工作中出现异常... " + ex);
        }
    } 

    spring配置文件:

    <bean id="logAspect" class="cn.test.aop.advice.defineAspectClass.impl.TestAspect"></bean>
              <aop:config>
                      <aop:pointcut id="pointcut" expression="execution(* cn.test.business.*.*(..))" />
                      <aop:aspect id="aspect" ref="logAspect">
                              <aop:before pointcut-ref="pointcut" method="doBefore"/>
                              <aop:after-returning pointcut-ref="pointcut" method="afterReturning" returning="retValue"/>
                              <aop:after-throwing pointcut-ref="pointcut" method="doThrowing" throwing="ex"/>
                              <aop:after pointcut-ref="pointcut" method="doAfter"/>
                              <aop:around pointcut-ref="pointcut" method="doAround"/>
                     </aop:aspect>
              </aop:config>





  • 相关阅读:
    linux下51单片机开发解决方案
    ubuntu下virtualbox配置hostonly网络
    标准c头文件
    linux下vim和bash配置文件
    排序算法
    系统空闲一段时间后关闭指定进程
    c常用字符串函数
    lubuntu自动登录(lxde)
    开源软件发展史
    awk命令(语言)
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256871.html
Copyright © 2020-2023  润新知