zoukankan      html  css  js  c++  java
  • Spring学习十四----------Spring AOP实例

    © 版权声明:本文为博主原创文章,转载请注明出处

    实例

    1.项目结构

    2.pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    
    	<modelVersion>4.0.0</modelVersion>
      
    	<groupId>org.spring</groupId>
    	<artifactId>Spring-AOP</artifactId>
    	<packaging>war</packaging>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>Spring-AOP Maven Webapp</name>
    	<url>http://maven.apache.org</url>
    	
    	<properties>
    		<!-- 统一spring版本 -->
    		<spring.version>4.3.8.RELEASE</spring.version>
    	</properties>
    	
    	<dependencies>
    		<!-- junit -->
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.12</version>
    			<scope>test</scope>
    		</dependency>
    		<!-- Spring Core -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-core</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-beans</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-context</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<!-- Spring AOP -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-aop</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<!-- AspectJ -->
    		<dependency>
    		    <groupId>aspectj</groupId>
    		    <artifactId>aspectjtools</artifactId>
    		    <version>1.5.4</version>
    		</dependency>
    	</dependencies>
    	
    	<build>
    		<finalName>Spring-AOP</finalName>
    	</build>
    	
    </project>
    

    3.AspectBiz.java

    package org.spring.aop.biz;
    
    public class AspectBiz {
    
    	/**
    	 * 执行正常的业务方法
    	 */
    	public void biz() {
    		
    		System.out.println("执行了AspectBiz中的业务方法,无异常");
    		
    	}
    	
    	/**
    	 * 执行存在异常的业务方法
    	 */
    	public void throwingBiz() {
    		
    		System.out.println("执行了AspectBiz中的业务方法,存在异常");
    		throw new RuntimeException();
    		
    	}
    	
    	/**
    	 * 执行正常的含参的业务方法
    	 * 
    	 * @param arg1
    	 * 				参数一
    	 * @param arg2
    	 * 				参数二
    	 */
    	public void paramterBiz(String arg1, int arg2) {
    		
    		System.out.println("执行了AspectBiz中的业务方法,参数是arg1:" + arg1 + "           arg2:" + arg2);
    		
    	}
    	
    }
    

    4.Aspect.java

    package org.spring.aop.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class Aspect {
    
    	/**
    	 * 前置通知
    	 */
    	public void before() {
    		
    		System.out.println("执行了Aspect切面的前置通知");
    		
    	}
    	
    	/**
    	 * 返回后通知,正常返回,抛出异常时不执行
    	 */
    	public void afterReturning() {
    		
    		System.out.println("执行了Aspect切面的正常返回后通知");
    		
    	}
    	
    	/**
    	 * 抛出异常后通知
    	 */
    	public void afterThrowing() {
    		
    		System.out.println("执行了Aspect切面的抛出异常后通知");
    		
    	}
    	
    	/**
    	 * 后通知,不管是否抛出异常
    	 */
    	public void after() {
    		
    		System.out.println("执行了Aspect切面的后通知");
    		
    	}
    	
    	/**
    	 * 环绕通知,环绕通知的第一个参数必须是ProceedingJoinPoint
    	 * 
    	 * @param pjp
    	 */
    	public Object around(ProceedingJoinPoint pjp) {
    		
    		Object obj = null;
    		try {
    			System.out.println("Aspect切面环绕通知开始执行");
    			obj = pjp.proceed();
    			System.out.println("Aspect切面环绕通知执行结束");
    		} catch (Throwable e) {
    			e.printStackTrace();
    		}
    		return obj;
    		
    	}
    	
    	/**
    	 * 含参环绕通知,环绕通知的第一个参数必须是ProceedingJoinPoint
    	 * 
    	 * @param pjp
    	 */
    	public Object aroundParamter(ProceedingJoinPoint pjp, String arg1, int arg2) {
    		
    		Object obj = null;
    		try {
    			System.out.println("Aspect切面环绕通知开始执行");
    			System.out.println("参数是arg1:" + arg1 + "        arg2:" + arg2);
    			obj = pjp.proceed();
    			System.out.println("Aspect切面环绕通知执行结束");
    		} catch (Throwable e) {
    			e.printStackTrace();
    		}
    		return obj;
    		
    	}
    	
    }
    

    5.Fit.java

    package org.spring.aop;
    
    public interface Fit {
    
    	public void filter();
    	
    }
    

    6.FitImpl.java

    package org.spring.aop.impl;
    
    import org.spring.aop.Fit;
    
    public class FitImpl implements Fit {
    
    	public void filter() {
    		
    		System.out.println("FitImpl filter.");
    		
    	}
    	
    }
    

    7.spring-aop.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 id="aspectBiz" class="org.spring.aop.biz.AspectBiz"/><!-- 业务逻辑类 -->
        
        <bean id="aspect" class="org.spring.aop.aspect.Aspect"/><!-- 切面类 -->
          
        <aop:config><!-- AOP配置 -->
        	<aop:aspect id="aspectAOP" ref="aspect"><!-- 配置切面 -->
        		<!-- 配置切入点,org.spring.aop.biz.AspectBiz类中的所有方法 -->
        		<aop:pointcut expression="execution(* org.spring.aop.biz.AspectBiz.*(..))" id="pointcut"/>
        		<aop:before method="before" pointcut-ref="pointcut"/><!-- 前置通知 -->
        		<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/><!-- 返回后通知 -->
        		<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/><!-- 抛出异常后通知 -->
        		<aop:after method="after" pointcut-ref="pointcut"/><!-- 后通知 -->
        		<aop:around method="around" pointcut-ref="pointcut"/><!-- 环绕通知 -->
        		<aop:around method="aroundParamter" 
        			pointcut="execution(* org.spring.aop.biz.AspectBiz.paramterBiz(String,int))
        			and args(arg1,arg2)"/><!-- 带参数的环绕通知 -->
        		<!-- Introduction,在不修改类代码的前提下,为类添加新的父类 -->
        		<aop:declare-parents types-matching="org.spring.aop.biz.*(+)" 
        			implement-interface="org.spring.aop.Fit"
        			default-impl="org.spring.aop.impl.FitImpl"/>
        	</aop:aspect>
        </aop:config>
        
    </beans>
    

    8.TestBase.java

    package org.spring.aop.test;
    
    import org.junit.Before;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.util.StringUtils;
    
    public class TestBase {
    
    	private ClassPathXmlApplicationContext context;
    	private String springXmlPath;
    	
    	/**
    	 * 无参构造器
    	 */
    	public TestBase() {
    	
    	}
    	
    	/**
    	 * 含参构造器,初始化spring配置文件路径
    	 * 
    	 * @param springXmlPath
    	 * 						spring配置文件路径
    	 */
    	public TestBase(String springXmlPath) {
    
    		this.springXmlPath = springXmlPath;
    		
    	}
    	
    	/**
    	 * 初始化加载spring配置文件到IOC容器中
    	 */
    	@Before
    	public void before() {
    		
    		if(StringUtils.isEmpty(springXmlPath)){
    			springXmlPath = "classpath:spring-*.xml";
    		}
    		context = new ClassPathXmlApplicationContext(springXmlPath.split("[,\s]+"));
    		context.start();
    		
    	}
    	
    	/**
    	 * 销毁IOC容器
    	 */
    	public void after() {
    		
    		if(context != null){
    			context.destroy();
    		}
    		
    	}
    	
    	/**
    	 * 根据bean ID获取bean对象
    	 * 
    	 * @param beanId
    	 * 					bean ID
    	 * @return
    	 */
    	public Object getBean(String beanId) {
    		
    		return context.getBean(beanId);
    		
    	}
    			
    }
    

    9.TestSpringAop.java

    package org.spring.aop.test;
    
    import org.junit.Test;
    import org.spring.aop.Fit;
    import org.spring.aop.biz.AspectBiz;
    
    public class TestSpringAop extends TestBase {
    
    	/**
    	 * 通过构造器初始化spring配置文件路径
    	 */
    	public TestSpringAop() {
    		
    		super("classpath:spring-aop.xml");
    		
    	}
    	
    	/**
    	 * 测试正常业务逻辑
    	 */
    	@Test
    	public void testAspect() {
    		
    		AspectBiz biz = (AspectBiz) super.getBean("aspectBiz");
    		biz.biz();
    		
    	}
    	
    	/**
    	 * 测试异常业务逻辑
    	 */
    	@Test
    	public void testThrowAspect() {
    		
    		AspectBiz biz = (AspectBiz) super.getBean("aspectBiz");
    		biz.throwingBiz();
    		
    	}
    	
    	/**
    	 * 测试含参数业务逻辑
    	 */
    	@Test
    	public void testParamterAspect() {
    		
    		AspectBiz biz = (AspectBiz) super.getBean("aspectBiz");
    		biz.paramterBiz("测试数据", 1234);
    		
    	}
    	
    	/**
    	 * 测试Introduction,在不修改类代码的前提下,为类添加新的方法和属性
    	 */
    	@Test
    	public void testIntroduction() {
    		
    		Fit fit = (Fit) super.getBean("aspectBiz");
    		fit.filter();
    		
    	}
    
    }
    

    10.效果预览

      10.1 执行testAspect方法

      10.2 执行testThrowAspect方法

      注:方法抛出异常后,并没有抛出异常后通知,而是执行了返回后通知,原因是因为配置了环绕通知,将环绕通知屏蔽后就正常了。

      10.3 执行testParamterAspect方法

      10.4 执行testIntroduction方法

    参考:http://www.imooc.com/video/4419

         http://www.imooc.com/video/4420

       http://www.imooc.com/video/4421

       http://www.imooc.com/video/4422

         http://www.imooc.com/video/4440

  • 相关阅读:
    索引
    IComparer 与 IComparable
    foreach
    修正needle在摘要认证时第二次请求仍返回401错误
    js笔记
    Ntp客户端
    c# 笔记
    android笔记
    nodejs笔记
    js 常用基本知识
  • 原文地址:https://www.cnblogs.com/jinjiyese153/p/6761925.html
Copyright © 2011-2022 走看看