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

实例:

1.项目结构

2.pom.xml

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3.  
  4. <modelVersion>4.0.0</modelVersion>
  5.  
  6. <groupId>org.spring</groupId>
  7. <artifactId>Spring-AOP-API</artifactId>
  8. <packaging>war</packaging>
  9. <version>0.0.1-SNAPSHOT</version>
  10. <name>Spring-AOP-API Maven Webapp</name>
  11. <url>http://maven.apache.org</url>
  12.  
  13. <properties>
  14. <spring.version>4.3.8.RELEASE</spring.version>
  15. </properties>
  16.  
  17. <dependencies>
  18. <!-- junit -->
  19. <dependency>
  20. <groupId>junit</groupId>
  21. <artifactId>junit</artifactId>
  22. <version>4.12</version>
  23. <scope>test</scope>
  24. </dependency>
  25. <!-- Spring Core -->
  26. <dependency>
  27. <groupId>org.springframework</groupId>
  28. <artifactId>spring-core</artifactId>
  29. <version>${spring.version}</version>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework</groupId>
  33. <artifactId>spring-beans</artifactId>
  34. <version>${spring.version}</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework</groupId>
  38. <artifactId>spring-context</artifactId>
  39. <version>${spring.version}</version>
  40. </dependency>
  41. </dependencies>
  42.  
  43. <build>
  44. <finalName>Spring-AOP-API</finalName>
  45. </build>
  46. </project>

3.BizLogic.java

  1. package org.spring.aop.api;
  2.  
  3. public interface BizLogic {
  4.  
  5. String save();
  6.  
  7. String saveEx();
  8.  
  9. }

4.BizLogicImpl.java

  1. package org.spring.aop.api;
  2.  
  3. public class BizLogicImpl implements BizLogic {
  4.  
  5. public String save() {
  6.  
  7. System.out.println("BizLogicImpl:BizLogicImpl save.");
  8. return "BizLogicImpl save";
  9.  
  10. }
  11.  
  12. public String saveEx() {
  13.  
  14. System.out.println("BizLogicImpl:BizLogicImpl save.");
  15. throw new RuntimeException();
  16.  
  17. }
  18.  
  19. }

5.CustomBeforeAdvice

  1. package org.spring.aop.api;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.MethodBeforeAdvice;
  6.  
  7. public class CustomBeforeAdvice implements MethodBeforeAdvice {
  8.  
  9. public void before(Method method, Object[] args, Object target) throws Throwable {
  10.  
  11. System.out.println("CustomBeforeAdvice:" + method.getName() + " " +
  12. target.getClass().getName());
  13.  
  14. }
  15.  
  16. }

6.CustomAfterReturnAdvice.java

  1. package org.spring.aop.api;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.AfterReturningAdvice;
  6.  
  7. public class CustomAfterReturnAdvice implements AfterReturningAdvice {
  8.  
  9. public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
  10. throws Throwable {
  11.  
  12. System.out.println("CustomAfterReturnAdvice:" + method.getName() + " "
  13. + target.getClass().getName() + " " + returnValue);
  14.  
  15. }
  16.  
  17. }

7.CustomThrowsAdvice.java

  1. package org.spring.aop.api;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.ThrowsAdvice;
  6.  
  7. public class CustomThrowsAdvice implements ThrowsAdvice {
  8.  
  9. public void afterThrowing(Exception ex) throws Throwable {
  10.  
  11. System.out.println("CustomThrowsAdvice afterThrowing 1");
  12.  
  13. }
  14.  
  15. public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
  16. throws Throwable {
  17.  
  18. System.out.println("CustomThrowsAdvice afterThrowing 2:" + method.getName() + " "
  19. + target.getClass().getName());
  20.  
  21. }
  22.  
  23. }

8.CustomMethodInterceptor.java

  1. package org.spring.aop.api;
  2.  
  3. import org.aopalliance.intercept.MethodInterceptor;
  4. import org.aopalliance.intercept.MethodInvocation;
  5.  
  6. public class CustomMethodInterceptor implements MethodInterceptor {
  7.  
  8. public Object invoke(MethodInvocation invocation) throws Throwable {
  9.  
  10. System.out.println("CustomMethodInterceptor 1:" + invocation.getMethod().getName()
  11. + " " + invocation.getStaticPart().getClass().getName());
  12. Object obj = invocation.proceed();
  13. System.out.println("CustomMethodInterceptor 2:" + obj);
  14. return obj;
  15.  
  16. }
  17.  
  18. }

9.Lockable.java

  1. package org.spring.aop.api.introduction;
  2.  
  3. /**
  4. * 接口
  5. *
  6. */
  7. public interface Lockable {
  8.  
  9. void lock();
  10.  
  11. void unlock();
  12.  
  13. boolean locked();
  14.  
  15. }

10.LockMixin.java

  1. package org.spring.aop.api.introduction;
  2.  
  3. import org.aopalliance.intercept.MethodInvocation;
  4. import org.springframework.aop.support.DelegatingIntroductionInterceptor;
  5.  
  6. /**
  7. * 实现类
  8. *
  9. */
  10. public class LockMixin extends DelegatingIntroductionInterceptor implements Lockable {
  11.  
  12. private static final long serialVersionUID = 1L;
  13.  
  14. private boolean locked;
  15.  
  16. public void lock() {
  17.  
  18. this.locked = true;
  19.  
  20. }
  21.  
  22. public void unlock() {
  23.  
  24. this.locked = false;
  25.  
  26. }
  27.  
  28. public boolean locked() {
  29.  
  30. return this.locked;
  31.  
  32. }
  33.  
  34. /**
  35. * 被锁定后不能使用setter方法改变值
  36. */
  37. @Override
  38. public Object invoke(MethodInvocation invocation) throws Throwable {
  39.  
  40. if(locked && invocation.getMethod().getName().indexOf("set") == 0){
  41. throw new RuntimeException();
  42. }
  43. return super.invoke(invocation);
  44.  
  45. }
  46.  
  47. }

11.LockMixinAdvisor.java

  1. package org.spring.aop.api.introduction;
  2.  
  3. import org.springframework.aop.support.DefaultIntroductionAdvisor;
  4.  
  5. /**
  6. * Introduction,在不改变代码的情况下,添加一个父类
  7. *
  8. */
  9. public class LockMixinAdvisor extends DefaultIntroductionAdvisor {
  10.  
  11. private static final long serialVersionUID = 1L;
  12.  
  13. public LockMixinAdvisor() {
  14.  
  15. super(new LockMixin(), Lockable.class);
  16.  
  17. }
  18.  
  19. }

12.Spring-aop-api.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6.  
  7. <!-- Before advice
  8. -一个简单的通知类型
  9. -只是进方法之前被调用,不需要MethodInvocation对象
  10. -前置通知可以在连接点执行之前插入自定义行为,但不能改变返回值
  11. -->
  12. <bean id="customBeforeAdvice" class="org.spring.aop.api.CustomBeforeAdvice"/>
  13.  
  14. <!-- Throws advice
  15. -如果连接点抛出异常,throws advice在连接点返回后被调用
  16. -如果throws-advice的方法抛出异常,那么它将覆盖原有异常
  17. -接口org.springframework.aop.ThrowsAdvice不包含任何方法,仅仅是一个声明,实现类需要实现类似下面的方法
  18. -void afterThrowing([Method, args, target], ThrowableSubclass)
  19. -->
  20. <bean id="customThrowsAdvice" class="org.spring.aop.api.CustomThrowsAdvice"/>
  21.  
  22. <!-- After Returning advice
  23. -后置通知必须实现org.springframework.aop.AfterReturningAdvice几口
  24. -可以访问返回值(但不能进行修改)、被调用的方法、方法的参数和目标
  25. -如果抛出异常,将会抛出拦截器链,替代返回值
  26. -->
  27. <bean id="customAfterReturnAdvice" class="org.spring.aop.api.CustomAfterReturnAdvice"/>
  28.  
  29. <!-- Interception around advice
  30. -Spring的切入点模型使得切入点可以独立与advice重用,以针对不同的advice可以使用相同的切入点
  31. -->
  32. <bean id="customMethodInterceptor" class="org.spring.aop.api.CustomMethodInterceptor"/>
  33.  
  34. <!-- Introduction advice
  35. -Spring把引入通知作为一种特殊的拦截通知
  36. -需要IntroductionAdvisor和IntroductionInterceptor
  37. -仅适用于类,不能和任何切入点一起使用
  38. -实例:如果调用lock()方法,希望所有的setter方法抛出LockedException异常。
  39. -代码:Lockalbe.java LockMixin.java LockMixinAdvisor.java
  40. -->
  41. <!-- Advisor API
  42. -Advisor是仅包含一个切入点表达式关联的单个通知的方面
  43. -除了introductions,advisor可以用于任何通知
  44. -org.springframework.aop.support.DefaultIntroductionAdvisor是最常用的advisor类,
  45. 它可以与MethodInterceptor,BeforeAdvice或者ThrowsAdvice一起使用
  46. -它可以混合在Spring同一个AOP代理的advisor和advice
  47. -->
  48.  
  49. <!-- 当使用方式三时,屏蔽该bean的定义 -->
  50. <!-- <bean id="bizLogicImplTarget" class="org.spring.aop.api.BizLogicImpl"/> -->
  51.  
  52. <!-- ###########################方式一:使用pointcutBean开始############################# -->
  53. <!-- 根据方法名匹配切入点pointcut -->
  54. <!-- <bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut">
  55. <property name="mappedNames">成员变量,匹配的方法名集合
  56. <list>
  57. <value>sa*</value>
  58. </list>
  59. </property>
  60. </bean>
  61.  
  62. <bean id="defaultAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
  63. <property name="advice" ref="customBeforeAdvice"/>接入点通知,若非接入点,则该通知不生效
  64. <property name="pointcut" ref="pointcutBean"/>接入点
  65. </bean> -->
  66.  
  67. <!-- ProxyFactoryBean
  68. -创建Spring AOP代理的基本方法是使用org.springframework.aop.framework.ProxyFactoryBean
  69. -这可以完全控制切入点和通知(advice)以及它们的顺序
  70. -ProxyFactoryBean实现里getObject()方法创建一个AOP代理包装一个目标对象
  71. -使用ProxyFactoryBean或者其它IOC相关类来创建AOP代理的最重要的好处是通知和切入点也可以由IOC来管理
  72. -被代理类没有实现任何接口,使用CGLIB代理,否则JDK代理
  73. -通过设置proxyTargetClass为true,可强制使用CGLIB
  74. -如果目标类实现了一个(或者多个)接口,那么创建代理的类型将依赖ProxyFactoryBean的配置
  75. -如果ProxyFactoryBean的proxyInterfaces属性设置为一个或多个全限定接口名,基于JDK的代理将被创建
  76. -如果ProxyFactoryBean的proxyInterfaces属性没有被设置,但是目标类实现了一个(或者更多)接口,那么proxyInterfaces
  77. 将自动检测到这个目标类已经实现了至少一个接口,创建一个基于JDK的代理
  78. -->
  79. <!-- <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
  80. <property name="target">为该类创建代理,由ProxyFactoryBean自己去判断是否实现了接口
  81. <ref bean="bizLogicImplTarget"/>
  82. </property>
  83. <property name="interceptorNames">执行该代理的时候执行的interceptor
  84. <list>
  85. <value>defaultAdvisor</value>
  86. <value>customAfterReturnAdvice</value>
  87. <value>customMethodInterceptor</value>
  88. <value>customThrowsAdvice</value>
  89. </list>
  90. </property>
  91. </bean> -->
  92. <!-- ###############################方式一结束######################################### -->
  93. <!-- ############################方式二:使用pointcutBean开始############################ -->
  94. <!-- <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
  95. <property name="proxyInterfaces">直接指定接口
  96. <value>org.spring.aop.api.BizLogic</value>
  97. </property>
  98. <property name="target">为该类创建代理,因为直接指定了接口,所以肯定是使用JDK代理
  99. <ref bean="bizLogicImplTarget"/>
  100. </property>
  101. <property name="interceptorNames">执行该代理的时候执行的interceptor
  102. <list>
  103. <value>customBeforeAdvice</value>
  104. <value>customAfterReturnAdvice</value>
  105. <value>customMethodInterceptor</value>
  106. <value>customThrowsAdvice</value>
  107. </list>
  108. </property>
  109. </bean> -->
  110. <!-- ###############################方式二结束######################################### -->
  111. <!-- ##############################方式三:使用匿名内部Bean############################### -->
  112. <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
  113. <property name="proxyInterfaces"><!-- 直接指定接口 -->
  114. <value>org.spring.aop.api.BizLogic</value>
  115. </property>
  116. <property name="target"><!-- 上面可以直接使用bean id获取bean对象,此时该bean对象没有被代理,配置的advice不会被执行 -->
  117. <bean class="org.spring.aop.api.BizLogicImpl"/>
  118. </property>
  119. <property name="interceptorNames"><!-- 执行该代理的时候执行的interceptor -->
  120. <list>
  121. <value>customBeforeAdvice</value>
  122. <value>customAfterReturnAdvice</value>
  123. <value>customMethodInterceptor</value>
  124. <value>customThrowsAdvice</value>
  125. </list>
  126. <!-- 使用global advisors
  127. -用*做通配,匹配所有拦截器加入通知链
  128. 此处只会执行customMethodInterceptor,因为只有该advice实现了Interceptor接口
  129. -->
  130. <!-- <list>
  131. <value>custom*</value>
  132. </list> -->
  133. </property>
  134. </bean>
  135. <!-- ###############################方式三结束######################################### -->
  136. <!-- ##############################方式四:简化的proxy定义############################### -->
  137. <!-- 简化的proxy定义
  138. -使用父子bean定义以及内部bean定义,可能会带来更清洁和更简洁的代理定义
  139. -->
  140. <!-- <bean id="baseProxyBean" class="org.springframework.aop.framework.ProxyFactoryBean"
  141. lazy-init="true" abstract="true"/>
  142.  
  143. <bean id="bizLogicImpl" parent="baseProxyBean">
  144. <property name="proxyInterfaces">直接指定接口
  145. <value>org.spring.aop.api.BizLogic</value>
  146. </property>
  147. <property name="target">上面可以直接使用bean id获取bean对象,此时该bean对象没有被代理,配置的advice不会被执行
  148. <bean class="org.spring.aop.api.BizLogicImpl"/>
  149. </property>
  150. <property name="interceptorNames">执行该代理的时候执行的interceptor
  151. <list>
  152. <value>customBeforeAdvice</value>
  153. <value>customAfterReturnAdvice</value>
  154. <value>customMethodInterceptor</value>
  155. <value>customThrowsAdvice</value>
  156. </list>
  157. </property>
  158. </bean> -->
  159. <!-- ###############################方式四结束######################################### -->
  160.  
  161. </beans>

13.TestBase.java

  1. package org.spring.aop.api.test;
  2.  
  3. import org.junit.After;
  4. import org.junit.Before;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. import org.springframework.util.StringUtils;
  7.  
  8. public class TestBase {
  9.  
  10. private ClassPathXmlApplicationContext context;
  11. private String springXmlPath;
  12.  
  13. /**
  14. * 无参构造器
  15. */
  16. public TestBase() {
  17.  
  18. }
  19.  
  20. /**
  21. * 含参构造器,初始化spring配置文件路径
  22. *
  23. * @param springXmlPath
  24. * spring配置文件路径
  25. */
  26. public TestBase(String springXmlPath) {
  27.  
  28. this.springXmlPath = springXmlPath;
  29.  
  30. }
  31.  
  32. /**
  33. * 初始化spring配置文件并加载到IOC容器中
  34. */
  35. @Before
  36. public void before() {
  37.  
  38. if(StringUtils.isEmpty(springXmlPath)) {
  39. springXmlPath = "classpath:spring-*.xml";
  40. }
  41. context = new ClassPathXmlApplicationContext(springXmlPath.split("[,\\s]+"));
  42. context.start();
  43.  
  44. }
  45.  
  46. /**
  47. * 销毁IOC容器
  48. */
  49. @After
  50. public void after() {
  51.  
  52. if(context != null){
  53. context.destroy();
  54. }
  55.  
  56. }
  57.  
  58. /**
  59. * 根据bean ID获取bean对象
  60. *
  61. * @param beanId
  62. * bean ID
  63. * @return
  64. */
  65. public Object getBean(String beanId) {
  66.  
  67. return context.getBean(beanId);
  68.  
  69. }
  70.  
  71. }

14.TestSpringAOPAPI.java

  1. package org.spring.aop.api.test;
  2.  
  3. import org.junit.Test;
  4. import org.spring.aop.api.BizLogic;
  5.  
  6. public class TestSpringAOPAPI extends TestBase {
  7.  
  8. /**
  9. * 通过构造器初始化spring配置文件
  10. */
  11. public TestSpringAOPAPI() {
  12.  
  13. super("classpath:spring-aop-api.xml");
  14.  
  15. }
  16.  
  17. /**
  18. * 测试正常方法
  19. */
  20. @Test
  21. public void testSave() {
  22.  
  23. BizLogic logic = (BizLogic) super.getBean("bizLogicImpl");
  24. logic.save();
  25.  
  26. }
  27.  
  28. /**
  29. * 测试存在异常的方法
  30. */
  31. @Test
  32. public void testsaveEx() {
  33.  
  34. BizLogic logic = (BizLogic) super.getBean("bizLogicImpl");
  35. logic.saveEx();
  36.  
  37. }
  38.  
  39. }

15.效果预览

  15.1 执行testSave方法

  15.2 执行testsaveEx方法

说明:其他几种方式已在spring-aop-api.xml中注明,可自行测试。

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

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

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

Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容的更多相关文章

  1. Spring学习(十五)----- Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  2. spring学习 十五 spring的自动注入

    一  :在 Spring 配置文件中对象名和 ref=”id” ,id 名相同使用自动注入,可以不配置<property/>,对应的注解@Autowired的作用 二: 两种配置办法 (1 ...

  3. Spring学习十四----------Spring AOP实例

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

  4. spring boot(十五)spring boot+thymeleaf+jpa增删改查示例

    快速上手 配置文件 pom包配置 pom包里面添加jpa和thymeleaf的相关包引用 <dependency> <groupId>org.springframework.b ...

  5. Spring 学习十五 AOP

    http://www.hongyanliren.com/2014m12/22797.html 1: 通知(advice): 就是你想要的功能,也就是安全.事物.日子等.先定义好,在想用的地方用一下.包 ...

  6. Spring学习(十九)----- Spring的五种事务配置详解

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

  7. spring学习 十四 注解AOP 通知传递参数

    我们在对切点进行增强时,不建议对切点进行任何修改,因此不加以使用@PointCut注解打在切点上,尽量只在Advice上打注解(Before,After等),如果要在通知中接受切点的参数,可以使用Jo ...

  8. Spring学习(十八)----- Spring AOP+AspectJ注解实例

    我们将向你展示如何将AspectJ注解集成到Spring AOP框架.在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法. 常见AspectJ的注解: @Before – 方法 ...

  9. Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)

    在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...

随机推荐

  1. java读取文件的基本操作

    import java.io.FileInputStream; /** * 使用FileInputStream读取文件 */ public class FileRead { /** * @param ...

  2. js setInterval 启用&停止

    以下面例子为说明: <title></title> <script src="Scripts/jquery-1.4.1-vsdoc.js" type= ...

  3. 利用Docker搭建本地https环境的完整步骤

    利用Docker搭建本地https环境的完整步骤 这篇文章主要给大家介绍了关于如何利用Docker搭建本地https环境的完整步骤,文中通过示例代码将实现的步骤介绍的非常详细,对大家的学习或者工作具有 ...

  4. Educational Codeforces Round 37 A B C D E F

    A. water the garden Code #include <bits/stdc++.h> #define maxn 210 using namespace std; typede ...

  5. 《手把手教你学C语言》学习笔记(2)---学习C语言的目标和方法

    一.学习C语言的目标主要是: 熟练掌握C语言的关键字,语法规则,程序控制等: 掌握基本的数据结构,数组.链表.栈和队列等: 掌握C语言中指针和内存.数组与指针.函数与指针.变量和指针.结构体和指针.硬 ...

  6. jquery 中的post和get方法同步问题

    解决方法: 在需要同步的js代码前修改ajax的async属性. 有两种设置方法: 1: $.ajaxSettings.async = false; 2: $.ajaxSetup({ async : ...

  7. cocoapods集成三方库遇到的坑

    什么都不想说直接上图 这是最近在管理三方库时遇到头疼的问题,刚开始一直怀疑是cocoapods或者ruby的版本问题但是升级到最新版还是同样的错误,后来又怀疑是资源文件的问题但是在同一时间不同地点集成 ...

  8. Hotspot JVM下,parallel与concurrent的区别

    转载于知乎 作者:Ted Mosby链接:https://www.zhihu.com/question/21535747/answer/144884632来源:知乎著作权归作者所有.商业转载请联系作者 ...

  9. 2018年东北农业大学春季校赛 K wyh的数列【数论/斐波那契数列大数取模/循环节】

    链接:https://www.nowcoder.com/acm/contest/93/K来源:牛客网 题目描述 wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F( ...

  10. Codeforces Round #450 (Div. 2) C. Remove Extra One【*模拟链表/一个数比前面所有数大就是个record。删掉一个数,让record的个数尽量多。】

    C. Remove Extra One time limit per test 2 seconds memory limit per test 256 megabytes input standard ...