Spring的核心思想的IOC和AOP。最近学习AOP,对切面的学习有了进一步的认识。

Spring用代理类包裹切面,把他们织入到Spring管理的bean中。也就是说代理类伪装成目标类,它会截取对目标类中方法的调用,让调用者对目标类的调用都先变成调用伪装类,伪装类中就先执行了切面,再把调用转发给真正的目标bean。这样可以实现对业务代码的最小化侵入。使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。Spring中日志记录,性能统计,安全控制,事务处理等都是通过AOP来管理的。

伪装类的实现有两种方式:1.实现和目标类相同的接口。这种兄弟模式下,spring会使用JDK的java.lang.reflect.Proxy类,它允许Spring动态生成一个新类来实现必要的接口,织入通知,并且把对这些接口的任何调用都转发到目标类。

2.生成子类调用,用子类来做为伪装类。这种父子模式下,spring使用CGLIB库生成目标类的一个子类,在创建这个子类的时候,spring织入通知,并且把对这个子类的调用委托到目标类。

相比之下,还是兄弟模式好些,能更好的实现松耦合,尤其在今天都高喊着面向接口编程的情况下,父子模式只是在没有实现接口的时候,也能织入通知,应当做一种例外。

下面看一个AOP的小应用。目的是为了在addStudent方法执行前后通过AOP来进行相关操作。

在上下文中配置aspectJ。

<aop:aspectj-autoproxy/>
//定义切面,切点。也可以通过注解来实现切面的和切点标识。
<aop:config>
<aop:aspect id="StudentServiceAspect" ref="studentServiceAspect">
<aop:pointcut id="businessService" expression="execution(* com.lufax.test.commen.studentService.*.*(..))"/>
<aop:before method="doBefore" pointcut-ref="businessService"/>
<aop:after method="doAfter" pointcut-ref="businessService"/>
<aop:around method="doAround" pointcut-ref="businessService"/>
</aop:aspect>
</aop:config>

下面定义studentService的接口。

public interface StudentService {
public void addStudent(String name);
}

studentService的实现类如下。

public class StudentServiceImp implements StudentService {

    public void addStudent(String name){
System.out.println("----正在添加" + name+"----");
}
}

以上接口和实现都是正常的业务逻辑。下面写切面。

public class StudentServiceAspect {
//在业务代码执行前运行
public void doBefore(){
System.out.println("类名:");
System.out.println("doBefore:开始添加学生");
}
//业务代码执行后运行
public void doAfter(JoinPoint jp){
System.out.println("doAfter:添加完毕");
//可以通过Joinpoint类来实现日志的打印。记录切点下类和方法名、参数,以便后续快速定位问题所在。
System.out.println("[类名+"+jp.getTarget().getClass().getName()+"],"+
"[方法名:"+jp.getSignature().getName()+"],"+
"[参数:"+jp.getArgs()[0]+"]");
}
//环绕通知,retVal是返回值。这里为null
public Object doAround(ProceedingJoinPoint pjp)throws Throwable{
System.out.println("doAround:加入前");
Object retVal= pjp.proceed();
System.out.println(retVal);
System.out.println("doAround:加入后");
return retVal;
}
}

通过注解实现。

@Aspect
public class StudentServiceAspect { @Before(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..)) ")
public void doBefore(){
System.out.println("类名:");
System.out.println("doBefore:开始添加学生");
} @After(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..))")
public void doAfter(JoinPoint jp){
System.out.println("doAfter:添加完毕");
System.out.println("[类名+"+jp.getTarget().getClass().getName()+"],"+
"[方法名:"+jp.getSignature().getName()+"],"+
"[参数:"+jp.getArgs()[0]+"]");
} @Around(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..))")
public Object doAround(ProceedingJoinPoint pjp)throws Throwable{
System.out.println("doAround:加入前");
Object retVal= pjp.proceed();
System.out.println(retVal);
System.out.println("doAround:加入后");
return retVal;
}
}

最后写测试类。

@Test
public void test_AopAspectJ() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","dataSource.xml");
StudentService studentService = (StudentService) applicationContext.getBean("studentService");
studentService.addStudent("张三");
}

运行结果如下:

类名:
doBefore:开始添加学生
doAround:加入前
----正在添加张三----
doAfter:添加完毕
[类名+com.lufax.test.commen.studentService.StudentServiceImp],[方法名:addStudent],[参数:张三]
null
doAround:加入后

Spring AOP理解的更多相关文章

  1. spring AOP理解和相关术语

    一.AOP理解 AOP:横向抽取机制,底层使用代理方式实现. 示例: 现有LogDAO接口以及实现Log接口的Log类.类有add的方法,现在要打印add方法的开始时间和结束时间.(即增强Log的ad ...

  2. spring aop 理解

    aop简介 aop是spring 的两大特性之一,还有IOC.主要提供面向切面的编程思想,区分于面向对象编程. aop原理(动态代理+反射) 在一个方法体中,可能会存在很多其他的方法调用,我们可以把每 ...

  3. Spring aop 原始的工作原理的理解

    理解完aop的名词解释,继续学习spring aop的工作原理. 首先明确aop到底是什么东西?又如何不违单一原则并实现交叉处理呢? 如果对它的认识只停留在面向切面编程,那就脏了.从oop(Objec ...

  4. 正确理解Spring AOP中的Around advice

    Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before ad ...

  5. 我所理解的Spring AOP的基本概念

    Spring AOP中的概念晦涩难懂,读官方文档更是像读天书,看了非常多样例后,写一些自己理解的一些spring的概念.要理解面向切面编程,要首先理解代理模式和动态代理模式. 如果一个OA系统中的一个 ...

  6. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  7. 简单直白的去理解AOP,了解Spring AOP,使用 @AspectJ - 读书笔记

    AOP = Aspect Oriental Programing  面向切面编程 文章里不讲AOP术语,什么连接点.切点.切面什么的,这玩意太绕,记不住也罢.旨在以简单.直白的方式理解AOP,理解Sp ...

  8. Spring Aop的理解和简单实现

    1.AOP概念 所说的面向切面编程其实就是在处理一系列业务逻辑的时候这一系列动作看成一个动作集合.比如连接数据库来说: 加载驱动-----获取class--------获取连接对象-------访问数 ...

  9. Spring AOP深入理解之拦截器调用

    Spring AOP深入理解之拦截器调用 Spring AOP代理对象生成回想 上一篇博客中:深入理解Spring AOP之二代理对象生成介绍了Spring代理对象是怎样生成的,当中重点介绍了JDK动 ...

随机推荐

  1. Android 性能测试初探(二)

    书接前文 Android 性能测试初探(一).上回大体介绍了下在 android 端的性能测试项,现在我们就细节测试项做一些阐述(包括如何自己 DIY 测试). 首先我们来说说启动时间.关于应用的启动 ...

  2. 【剑指Offer】16、合并两个排序的链表

      题目描述:   输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.   解题思路:   首先需要判断几个特殊情况,即判断输入的两个指针是否为空.如果第一个 ...

  3. Node.js+Protractor+vscode搭建测试环境(1)

    1.protractor简介 官网地址:http://www.protractortest.org/ Protractor是一个end-to-end的测试框架,从网络上得到的答案是Protractor ...

  4. UVA1339 - Ancient Cipher 【字符串+排序】【紫书例题4.1】

    题意:给定两个字符串,你可以替换或者置换,替换是指可以将相同的字母替换为任意一个字母,而置换是指将字母替换为下一个,如A替换B,B替换为C,,,Z替换为A.你需要判断是否可以通过一系列操作使两个字符串 ...

  5. html_entity_decode()、空格、&nbsp; 乱码问题

    普通 ASCII 码空格为 32,但是浏览器会对普通空格进行自动归并,也就是如果你输入10个 0x20 的空格在HTML页面里面,可能会被合并成一个空格. 如果想要一致的呈现多个空格,就要用到 编码标 ...

  6. GitLab权限介绍

    访问权限 - Visibility Level 这个是在建立项目时就需要选定的,主要用于决定哪些人可以访问此项目,包含3种 Private - 私有,只有属于该项目成员才有原先查看 Internal ...

  7. cannot find -lGL

    解决方法: 以下操作都在root权限下进行! 1.按照提示安装对应的库文件,fedora安装库件的格式:yum install libxxx(你要装的库),如果已经安装GL库,会显示已经安装 Ps:如 ...

  8. Solr Update插件自定义Update Chain按条件更新索引

    背景:基于call客,来电和跟进记录等多个数据来源的用户文档,需要在更新是判断首来源的时间. 如对电话号码11xxxx来说,来电时间是今天,call客时间是昨天,而call客数据又可能因为网络原因晚上 ...

  9. 洛谷——P2038 无线网络发射器选址

    https://www.luogu.org/problem/show?pid=2038 题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城 ...

  10. spring mvc接收http参数

    1.http协议携带参数,无外乎两个三个存储地点:1.url上 ,2.header里 3.body里. 2.get请求是没有body的,数据全都放在url上,以?xx&xxx形式.注:get请 ...