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
© 版权声明:本文为博主原创文章,转载请注明出处