为了学习这篇文章里面下载的代码:http://www.cnblogs.com/charlesblc/p/6083687.html

需要用Intellij导入一个已有工程。源文件原始内容也可见:link

选择 Import Project -> "Create Project from existing sources" ->选择root目录,一步步选择完毕。

为了从百度maven服务器更快的下载,在pom.xml最下面加上以下repo地址:

<repositories><repository><id>nexus-public</id><url>http://maven.scm.baidu.com:8081/nexus/content/groups/public</url></repository><repository><id>nexus-public-snapshots</id><url>http://maven.scm.baidu.com:8081/nexus/content/groups/public-snapshots</url></repository>
</repositories>

然后可能需要在报错的文件里用 option+enter进行一些错误的更正。

然后在project structure里面进行一些artifact的添加,就可以生成JAR。

一直在报错找不到依赖文件。看了一下 Project里面有两个module,删掉其中的main,只留aop。然后就不再报错啦。。。

然后看例子。

demo4

CGLib 动态代理

我们使用开源的 CGLib 类库可以代理没有接口的类,这样就弥补了 JDK 的不足。

demo7

抛出异常AOP

Hello! Jack
---------- Throw Exception ----------
Target Class: aop.demo7.GreetingImpl
Method Name: sayHello
Exception Message: Error
-------------------------------------
Exception in thread "main" java.lang.RuntimeException: Error
......Process finished with exit code 1

demo8

Spring AOP:引入增强

以上提到的都是对方法的增强,那能否对类进行增强呢?用 AOP 的行话来讲,对方法的增强叫做 Weaving(织入),而对类的增强叫做 Introduction(引入)。而 Introduction Advice(引入增强)就是对类的功能增强,它也是 Spring AOP 提供的最后一种增强。

@Component
public class GreetingIntroAdvice extends DelegatingIntroductionInterceptor implements Apology {public void saySorry(String name) {System.out.println("Sorry! " + name);}@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {return super.invoke(invocation);}
}

然后在spring的配置文件里面这样配:

<bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="interfaces" value="aop.demo8.Apology"/><property name="target" ref="greetingImpl"/><property name="interceptorNames" value="greetingIntroAdvice"/><property name="proxyTargetClass" value="true"/>
</bean>

需要注意 proxyTargetClass 属性,它表明是否代理目标类,默认为 false,也就是代理接口了,此时 Spring 就用 JDK 动态代理。如果为 true,那么 Spring 就用 CGLib 动态代理。这简直就是太方便了.

9. Spring AOP:切面

配置如下:

<bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="advice" ref="greetingAroundAdvice"/><property name="pattern" value="aop.demo9.GreetingImpl.good.*"/></bean><bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="greetingImpl"/><property name="interceptorNames" value="greetingAdvisor"/><property name="proxyTargetClass" value="true"/></bean>

10. Spring AOP:自动代理(扫描 Bean 名称)

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames" value="*Impl"/><property name="interceptorNames" value="greetingAroundAdvice"/><property name="optimize" value="true"/></bean>

通过以上配置,就可以自动扫描bean进行匹配。

以上使用 BeanNameAutoProxyCreator 只为后缀为“Impl”的 Bean 生成代理。需要注意的是,这个地方我们不能定义代理接口,也就是 interfaces 属性,因为我们根本就不知道这些 Bean 到底实现了多少接口。此时不能代理接口,而只能代理类。所以这里提供了一个新的配置项,它就是 optimize。若为 true 时,则可对代理生成策略进行优化(默认是 false 的)。也就是说,如果该类有接口,就代理接口(使用 JDK 动态代理);如果没有接口,就代理类(使用 CGLib 动态代理)。而并非像之前使用的 proxyTargetClass 属性那样,强制代理类,而不考虑代理接口的方式。可见 Spring AOP 确实为我们提供了很多很好地服务。

11. Spring AOP:自动代理(扫描切面配置)

如果既要自动扫描bean,并且匹配方法,可以用下面的

   <bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="pattern" value="aop.demo11.GreetingImpl.good.*"/><property name="advice" ref="greetingAroundAdvice"/></bean><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"><property name="optimize" value="true"/></bean>

但是匹配的时候,还是有一些问题。很麻烦。

在 Spring 配置文件中,仍然会存在大量的切面配置。然而在有很多情况下 Spring AOP 所提供的切面类真的不太够用了,比如:想拦截指定注解的方法,我们就必须扩展 DefaultPointcutAdvisor 类,自定义一个切面类,然后在 Spring 配置文件中进行切面配置。不做不知道,做了您就知道相当麻烦了。

12. Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)

主要代码如下:

@Aspect
@Component
public class GreetingAspect {@Around("execution(* aop.demo12.GreetingImpl.*(..))")public Object around(ProceedingJoinPoint pjp) throws Throwable {before();Object result = pjp.proceed();after();return result;}private void before() {System.out.println("Before");}private void after() {System.out.println("After");}
}

下面重点来分析一下这个切点表达式:

execution(* aop.demo.GreetingImpl.*(..))

  • execution():表示拦截方法,括号中可定义需要匹配的规则。

  • 第一个“*”:表示方法的返回值是任意的。

  • 第二个“*”:表示匹配该类中所有的方法。

  • (..):表示方法的参数是任意的。

XML配置内容:

    <context:component-scan base-package="aop.demo"/><aop:aspectj-autoproxy proxy-target-class="true"/>

需要注意的是 proxy-target-class="true" 属性,它的默认值是 false,默认只能代理接口(使用 JDK 动态代理),当为 true 时,才能代理目标类(使用 CGLib 动态代理)。

13. Spring + AspectJ(基于注解:通过 AspectJ @annotation 表达式拦截方法) 

首先用annotation定义一个tag

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Tag {
}

然后针对这个tag来写增强方法:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Aspect
@Component
public class GreetingAspect {@Around("@annotation(aop.demo13.Tag)")public Object around(ProceedingJoinPoint pjp) throws Throwable {before();Object result = pjp.proceed();after();return result;}private void before() {System.out.println("Before");}private void after() {System.out.println("After");}
}

最后,在方法上面打上tag就可以了:

@Component
public class GreetingImpl implements Greeting {@Tagpublic void sayHello(String name) {System.out.println("Hello! " + name);}
}

除了 @Around 注解外,其实还有几个相关的注解,稍微归纳一下吧:

  • @Before:前置增强

  • @After:后置增强

  • @Around:环绕增强

  • @AfterThrowing:抛出增强

  • @DeclareParents:引入增强

此外还有一个 @AfterReturning(返回后增强),也可理解为 Finally 增强,相当于 finally 语句,它是在方法结束后执行的,也就说说,它比 @After 还要晚一些。

最后一个 @DeclareParents 竟然就是引入增强!为什么不叫做 @Introduction 呢?我也不知道为什么,但它干的活就是引入增强。

14. Spring + AspectJ(引入增强)

首先要定义一个aspect类:

@Aspect
@Component
public class GreetingAspect {@DeclareParents(value = "aop.demo14.GreetingImpl", defaultImpl = ApologyImpl.class)private Apology apology;
}

在这个接口上标注了 @DeclareParents 注解,该注解有两个属性:

  • value:目标类

  • defaultImpl:引入接口的默认实现类

然后在实现一个ApologyImpl类:

package aop.demo14;public class ApologyImpl implements Apology {public void saySorry(String name) {System.out.println("Sorry! " + name);}
}

从 Spring ApplicationContext 中获取 greetingImpl 对象(其实是个代理对象),可转型为自己静态实现的接口 Greeting,也可转型为自己动态实现的接口 Apology,切换起来非常方便。

使用 AspectJ 的引入增强比原来的 Spring AOP 的引入增强更加方便了,而且还可面向接口编程(以前只能面向实现类),这也算一个非常巨大的突破。

上面这一句指的是如下,可以直接转型为Greeting,而不需要转型为GreetingImpl这个类了

public class Client {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("aop/demo14/spring.xml");Greeting greeting = (Greeting) context.getBean("greetingImpl");greeting.sayHello("Jack");Apology apology = (Apology) greeting;apology.saySorry("Jack");}
}

15. Spring + AspectJ(基于配置)

仍然还是有用户不能尝试这些特性,因为他们还在使用 JDK 1.4(根本就没有注解这个东西),怎么办呢?没想到 Spring AOP 为那些遗留系统也考虑到了。

demo15基本完全基于配置,因为代码很简单:

package aop;public interface Greeting {void sayHello(String name);
}

而配置会复杂一些:

    <bean id="greetingImpl" class="aop.demo15.GreetingImpl"/><bean id="greetingAspect" class="aop.demo15.GreetingAspect"/><aop:config><aop:aspect ref="greetingAspect"><aop:around method="around" pointcut="execution(* aop.demo15.GreetingImpl.*(..))"/></aop:aspect></aop:config>

使用 <aop:config> 元素来进行 AOP 配置,在其子元素中配置切面,包括增强类型、目标方法、切点等信息。

无论您是不能使用注解,还是不愿意使用注解,Spring AOP 都能为您提供全方位的服务。

下面这张图非常好。

给一张牛逼的高清无码思维导图,总结一下以上各个知识点:

再来一张表格,总结一下各类增强类型所对应的解决方案:

增强类型 基于 AOP 接口 基于 @Aspect 基于 <aop:config>
Before Advice(前置增强) MethodBeforeAdvice @Before <aop:before>
AfterAdvice(后置增强) AfterReturningAdvice @After <aop:after>
AroundAdvice(环绕增强) MethodInterceptor @Around <aop:around>
ThrowsAdvice(抛出增强 ThrowsAdvice @AfterThrowing <aop:after-throwing>
IntroductionAdvice(引入增强) DelegatingIntroductionInterceptor @DeclareParents <aop:declare-parents>

最后给一张 UML 类图描述一下 Spring AOP 的整体架构:

最后,再记录一下原文地址:link1   link2(续)

代码位置:/Users/baidu/Documents/Data/Work/Code/Demo_Code/aop_demo/

(完)

转载于:https://www.cnblogs.com/charlesblc/p/6092842.html

在Intellij上面导入项目 AOP示例项目 AspectJ学习 Spring AoP学习相关推荐

  1. AspectJ和Spring AOP(java动态代理和CGLIB)简单介绍

    1.AOP介绍 什么是AOP:AOP就是面向切面编程.使用的背景: 1)我们的振隆维护着一千个方法,一天老板让振隆把这一千个方法都要加上事务代码(统一代码) 2)振隆咬咬牙,添加了一个新的方法,然后让 ...

  2. Spring 学习——Spring AOP——AOP配置篇Advice(有参数传递)

    声明通知Advice 配置方式(以前置通知为例子) 方式一 <aop:config> <aop:aspect id="ikAspectAop" ref=" ...

  3. 一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  4. IntelliJ IDEA导入多个eclipse项目到同一个workspace下

    IntelliJ IDEA 与eclipse在新建项目上工作区的叫法略有不同,区别见下图. 我们在eclipse都是在新建的workspace目录下新建我们的项目,但是在IDEA中没有workspac ...

  5. Intellij Idea 导入多个maven项目展示在左侧栏Maven Projects

    刚刚要开始从eclipse切换成idea,据说idea功能强大,可是刚刚开始使用很多不习惯,导入第二个maven项目时之前的项目就没了,比较苦恼,下面介绍下导入多个maven项目展示在左侧栏Maven ...

  6. 初步学习Spring Aop使用之注解方式

    前言: 这里就主要演示Spring中Aop使用注解是怎么使用,如果需要了解更多Aop相关概念,可查看相关资料的介绍 一.项目目录 [标记文件为主要文件] 二.各个文件的代码 AopServer.jav ...

  7. spring aop不执行_使用Spring AOP重试方法执行

    spring aop不执行 我的一位博客关注者发送了一封电子邮件,要求我显示" Spring AOP的RealWorld用法"示例. 他提到,在大多数示例中,都演示了Spring ...

  8. 基于@AspectJ配置Spring AOP之一--转

    原文地址:http://tech.it168.com/j/2007-08-30/200708302209432.shtml 概述 在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并 ...

  9. java aop管理权限_基于spring aop 权限管理系统原型 - andyj2ee - BlogJava

    此权限管理系统把待访问的业务层方法做为权限管理中的资源,通过spring aop 对接口方法进行拦截,来实现权限的管理,可以实现细粒度的权限控制. 在上文体验了spring aop 一些特性,aop ...

最新文章

  1. MongoDB(一):简介
  2. 用神经网络构造一个基于分类的多体系统
  3. 【安全漏洞】Cisco命令注入漏洞CVE-2021-1414分析
  4. STL的forward_list链表
  5. 2013\National _C_C++_C\1.好好学习
  6. 富二代谈起中国做技术的地位(转载)
  7. java自定义标签简单_JSP 自定义标签之一 简单实例
  8. ChaiNext:市场短期内延续区间震荡
  9. linux 权限加号是,请教:drwxrwxr-x   什么权限后面有个加号,代表什么意思
  10. 计算机职称评定认可增刊吗,核心期刊增刊评定职称可以用吗?
  11. SqlLoader(Sqlldr) 的用法
  12. Xpose模块抓取函数功能学习笔记
  13. 最新github clone方法
  14. 实验吧-欢迎来到地狱题解
  15. Docker三剑客详解
  16. 【Pygame实战】妈耶~这款经典的《俄罗斯方块儿》竟这么厉害......
  17. 一键生成惊雷等喊麦歌词
  18. KF、EKF、UKF、ESKF、PF对比
  19. 【调剂】南华大学2021硕士研究生招生调剂公告
  20. Linux常见命令及含义

热门文章

  1. c语言测序,一次Hi-C建库测序,两种分析,你不心动?
  2. php判断一个数是否是回文数,每周一道算法题001:回文数
  3. linux配置4g网络命令_Linux网络基本配置命令
  4. python面试题_Python面试题大全
  5. php putcontent,PHP函数file_get_content及file_put_content介绍
  6. 建立时间裕量与保持时间裕量的简单理解
  7. 【 FPGA 】状态机的模型之Moore型状态机
  8. Android自定义组合控件
  9. oracle 体系结构及内存管理 13_事务
  10. Python之字符编码(Day10)