目录
Spring基于XML配置的AOP实现
/    

Spring基于XML配置的AOP实现

基于xml配置的aop实现以及例子

通知类型

  1. 环绕通知(around)
    • 环绕通知是在目标方法执行前和执行后实施增强,可用于日志记录、事务处理等功能。
    • <aop:around><aop:aspect>元素的子元素,属性method指定环绕通知方法,属性pointcut-ref指定关联的切入点。
  2. 前置通知(before)
    • 是在目标方法执行前实施增强,可应用于权限管理等功能。
    • <aop:before>, 属性method指定前置通知方法,属性pointcut-ref指定关联的切入点。
  3. 后置返回通知(afterReturning)
    • 是在方法目标方法执行成功后实施增强,可应用于关闭流、删除临时文件等功能。
    • <aop:after-returning>, 属性method指定后置返回通知方法,属性pointcut-ref指定关联的切入点。
  4. 后置(最终)通知(after)
    • 在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该类的通知,该类的通知可应用于释放资源。
    • <aop:after>, 属性method指定后置(最终)通知,属性pointcut-ref指定关联的切入点。
  5. 异常通知 (afterThrowing)
    • 是在方法抛出异常后实施增强,可应用于处理异常、记录日志等功能。
    • <aop:after-throwing>, 属性method指定异常通知 ,属性pointcut-ref指定关联的切入点。
  6. 引入通知
    • 是在目标类中添加一些新的方法和属性,可应用于修改目标类(增强类)
    • <aop:declare-parents>, 给通知引入新的额外接口,增强功能。(不要求掌握)

导入相关jar包

  • Spring-aspects-5.0.2.release.jar

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
    
    
  • aspectjweaver-1.8.13.jar

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    
    

例子

maven的依赖坐标

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
<!--      <scope>test</scope>-->
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
	<dependency>
	    <groupId>aopalliance</groupId>
	    <artifactId>aopalliance</artifactId>
	    <version>1.0</version>
	</dependency>
	<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-aspects</artifactId>
	    <version>5.2.0.RELEASE</version>
	</dependency>
	<dependency>
	    <groupId>org.aspectj</groupId>
	    <artifactId>aspectjweaver</artifactId>
	    <version>1.9.4</version>
	</dependency>

  </dependencies>

创建切面类

  • MyAspect.java

    package cn.lacknb.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    
    /*
     * 切面类
     * 在此类中编写各种类型的通知
     * */
    
    public class MyAspect {
    
    	/*
    	 * 前置通知,使用JoinPonit接口作为参数获得目标对象信息
    	 * 
    	 * */
    	public void before(JoinPoint jp){
    		System.out.println("前置通知:模拟权限控制");
    		System.out.println(",目标对象:" + jp.getTarget()
    		+ ",被增强处理的方法:" + jp.getSignature().getName());
    	}
    
    	/*
    	 * 后置返回通知
    	 * 
    	 * */
    	public void afterReturning(JoinPoint jp){
    		System.out.println("后置返回通知:" + "模拟删除临时文件");
    		System.out.println(",被增强处理的方法: " + jp.getSignature().getName());
    	}
    
    	/*
    	 * 环绕通知
    	 * ProceedingJoinPoint是JoinPoint的子接口,代表可以执行的目标方法
    	 * 返回值的类型必须是Object
    	 * 必须一个参数是ProceedingJoinPoint类型
    	 * 必须throws Throwable
    	 * */
    	public Object around(ProceedingJoinPoint pjp) throws Throwable{
    		// 开始
    		System.out.println("环绕开始:执行目标在前,模拟开启事务");
    		// 执行当前目标方法
    		Object obj = pjp.proceed();
    		// 结束
    		System.out.println("环绕结束:执行目标方法后,模拟关闭事务");
    		return obj;
    	}
    
    	/*
    	 * 异常通知
    	 * */
    	public void except(Throwable e){
    		System.out.println("异常通知:" + "程序执行异常" + e.getMessage());
    	}
    
    	/*
    	 * 后置最终通知
    	 * */
    
    	public void after(){
    		System.out.println("最终通知:模拟释放资源");
    	}
    
    }
    
    

创建接口和实现方法

  • TestDao.java

    package cn.lacknb.dao;
    
    public interface TestDao {
    	public void save();
    	public void modify();
    	public void delete();
    }
    
    
  • TestDaoImpl.java

    package cn.lacknb.dao;
    
    public class TestDaoImpl implements TestDao {
    
    	public void save(){
    		System.out.println("保存");
    	}
    
    	public void modify(){
    		System.out.println("修改");
    	}
    	public void delete(){
    		System.out.println("删除");
    	}
    
    }
    
    

创建额配置文件,并编写相关配置

  • applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="
              http://www.springframework.org/schema/beans    
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!-- bean definitions here -->
    
     	<!-- 定义目标对象 -->
     	<bean id="testDao" class="cn.lacknb.dao.TestDaoImpl"/>
     	<!-- 定义切面 -->
     	<bean id="myAspect" class="cn.lacknb.aspect.MyAspect"/>
     	<!-- aop配置 -->
     	<aop:config>
     		<!-- 配置切面 -->
     		<aop:aspect ref="myAspect">
     			<!-- 配置切入点,通知增强哪些方法 -->
     			<aop:pointcut expression="execution(* cn.lacknb.dao.*.*(..))" id="myPointcut"/>
     			<!-- 将通知于切入点关联 -->
     			<!-- 关联前置通知 -->
     			<aop:before method="before" pointcut-ref="myPointcut"/>
     		</aop:aspect>
     	</aop:config>
    
    </beans>
    

创建测试类

  • MyTest.java

    package cn.lacknb.test;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.lacknb.dao.TestDao;
    
    public class MyTest {
    
    	ApplicationContext context = null;
    	@Before
    	public void init(){
    		context = new ClassPathXmlApplicationContext("applicationContext.xml");
    	}
    
    	@Test
    	public void test01(){
    		TestDao test = (TestDao) context.getBean("testDao");
    		test.save();
    		test.delete();
    		test.modify();
    	}
    
    }
    

前置通知测试

K2QCOP.png

后置返回通知

  • xml文件

    <!-- 关联后置返回通知,在目标方法成功执行后执行 -->
    <aop:after-returning method="afterReturning" pointcut-ref="myPointcut"/>
    

K2QU61.png

关联环绕通知

  • xml文件

    <!-- 关联环绕通知 -->
    <aop:around method="around" pointcut-ref="myPointcut"/>
    
  • 结果

    K2Qcpd.png

关联异常通知

  • xml文件

    <!-- 关联异常通知,没有异常发生时将不会执行增强, throwing属性设置通知的第二个参数的名称 -->
    <aop:after-throwing method="except" pointcut-ref="myPointcut" throwing="e"/>
    

关联后置最终通知

  • xml文件

    <!-- 关联后置最终通知, 不管目标方法是否成功都要执行 -->
    <aop:after method="after" pointcut-ref="myPointcut"/>
    
  • 结果

    K2licR.png


标题:Spring基于XML配置的AOP实现
作者:gitsilence
地址:https://blog.lacknb.cn/articles/2019/10/30/1577974163829.html