继续上一节的内容,多几个jar包:

aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想。AOP底层也是面向对象;只不过面向的不是普通的Object对象,而是特殊的AOP对象。AOP的关注点是组成系统的非核心通用服务模块(比如登录检查等),相对于普通对象,aop不需要通过继承、方法调用的方式来提供功能,只需要在xml文件中以引用的方式,将非核心服务功能引用给需要改功能的核心业务逻辑对象或方法中。最终实现对象的解耦。spring 中ioc技术实现了核心业务逻辑对象之间的解耦(如LoginAction与DaoImpl)

AOP可以说是Spring中最难理解的一个知识点了,你可能网上找了很多资料,也买过很多本书,但都不是很理解到底什么是AOP?我曾经也是琢磨了好久才有了一定的了解。那么,到底怎么讲这个知识点呢。来不及解释了,快上车!听完这个例子,我相信你一定会对AOP有一个非常深刻的理解!

让我们新建一个英雄类:

  1. package com.spring.bean;
  2. public class Hero {
  3. private String heroName;
  4. private String type;
  5. private String description;
  6. public String getHeroName() {
  7. return heroName;
  8. }
  9. public void setHeroName(String heroName) {
  10. this.heroName = heroName;
  11. }
  12. public String getType() {
  13. return type;
  14. }
  15. public void setType(String type) {
  16. this.type = type;
  17. }
  18. public String getDescription() {
  19. return description;
  20. }
  21. public void setDescription(String description) {
  22. this.description = description;
  23. }
  24. @Override
  25. public String toString() {
  26. return "Hero [heroName=" + heroName + ", type=" + type + ", description=" + description + "]";
  27. }
  28. }

再来个露娜类,继承自英雄类:

啊啊啊,放错图片了,应该是这个:

  1. package com.spring.bean;
  2. public class Luna extends Hero{
  3. /**
  4. * 秀操作
  5. */
  6. public void operation(){
  7. System.out.println("看我月下无限连!");
  8. }
  9. /**
  10. * 跑路
  11. */
  12. public void run(){
  13. System.out.println("我操,大空了,赶紧跑!");
  14. }
  15. /**
  16. * 发信息
  17. * @param str
  18. */
  19. public void say(String str){
  20. System.out.println(str);
  21. }
  22. }

可以看到,露娜类有三个方法,分别是秀操作,跑路和发信息。

再写一个团战类:

  1. package com.spring.test;
  2. import com.spring.bean.Luna;
  3. /**
  4. * 团战类
  5. * @author Administrator
  6. *
  7. */
  8. public class Battle {
  9. public void tuan(){
  10. Luna luna = new Luna();
  11. luna.say("上去开团!");
  12. luna.operation();
  13. }
  14. }

测试代码如下:

  1. ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
  2. Battle battle = (Battle)context.getBean("Battle");
  3. battle.tuan();

我们用spring把Battle类配上去。

spring-aop.xml

  1. <bean id = 'Battle' class="com.spring.test.Battle"></bean>

运行测试代码:



在团战方法里面,我们新建一个露娜的对象,然后发出信息“上去开团”,接着又秀了一把操作。这是一个比较普通的流程。而事实上,露娜可能需要在团战前就提醒我方队友“等我集合打团”,不要人都没齐,队友就无脑往前冲。OK,我们如何通过代码来实现这个过程呢?很显然,这个过程需要在团战方法执行之前就被执行。这就需要AOP面向切面的技术了。

我们需要写一个类,实现MethodBeforeAdvice接口。

  1. /**
  2. * Notice 定义一个通知打团的信号 - 团战之前
  3. * @author Administrator
  4. *
  5. */
  6. public class BeforeTuanZhan implements MethodBeforeAdvice{
  7. @Override
  8. public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
  9. System.out.print(this.getClass().getName() + " -- ");
  10. Luna luna = new Luna();
  11. luna.setHeroName("露娜");
  12. luna.setType("战士/法师");
  13. luna.setDescription("月光女神");
  14. luna.say("等我集合打团!");
  15. }
  16. }

我们希望这个方法在团战之前就被执行,怎么做呢?没错,就是在XML文件中做如下配置:

  1. <bean id = 'BeforeTuanZhan' class="com.spring.service.BeforeTuanZhan"></bean>
  2. <aop:config>
  3. <!-- 定义所有可供露娜切入的点(方法) -->
  4. <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
  5. <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
  6. <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
  7. </aop:config>

execution(* com.spring.test.Battle.*(..))

这句话的含义就是,返回值为任意,com.spring.test包里面的Battle类,这个类里面所有的方法都需要切入。所谓的切入,就是在方法执行前,执行中,发生异常的时候执行某个其他的方法。执行中用的不多,一般就用另外三种情况。

现在,我们重新执行测试代码:

  1. ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
  2. Battle battle = (Battle)context.getBean("Battle");
  3. battle.tuan();

现在各位想一下,如果团战打赢了怎么办,是不是马上就该去推塔或者打龙啊,这个时候,如果队友团战打赢了就发呆,那就很坑了。所以呢,你这个时候就得提醒队友下一步该做什么,这个提醒的步骤是在团战方法执行结束后才发生的。

我们需要新建一个AfterTuanZhan类,实现AfterReturningAdvice接口。

  1. /**
  2. * Notice 定义一个团战结束后的类 - 团战之后
  3. * @author Administrator
  4. */
  5. public class AfterTuanZhan implements AfterReturningAdvice{
  6. @Override
  7. public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
  8. System.out.print(this.getClass().getName() + " -- ");
  9. Luna luna = new Luna();
  10. luna.setHeroName("露娜");
  11. luna.setType("战士/法师");
  12. luna.setDescription("月光女神");
  13. luna.say("进攻敌方防御塔!");
  14. }
  15. }

配置到spring-aop.xml中:

  1. <bean id = 'AfterTuanZhan' class="com.spring.service.AfterTuanZhan"></bean>
  2. <!-- 定义一个切面 -->
  3. <aop:config>
  4. <!-- 定义所有可供露娜切入的点(方法) -->
  5. <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
  6. <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
  7. <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
  8. <aop:advisor advice-ref="AfterTuanZhan" pointcut-ref="pointcut"/>
  9. </aop:config>

现在,我们重新执行测试代码:

  1. ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
  2. Battle battle = (Battle)context.getBean("Battle");
  3. battle.tuan();

再来说说万一团战失利的情况,比如露娜断大了咋办,没错,这个时候就是团战发生了异常,我们在Battle类中手动设置一个异常:

  1. /**
  2. * 团战类
  3. * @author Administrator
  4. *
  5. */
  6. public class Battle {
  7. public void tuan(){
  8. Luna luna = new Luna();
  9. luna.say("上去开团!");
  10. luna.operation();
  11. int i = 1 / 0 ;
  12. }
  13. }

然后,编写TuanZhanException类,实现ThrowsAdvice接口:

  1. /**
  2. * 定义一个团战异常类,万一出现情况就进入这个类
  3. * @author Administrator
  4. *
  5. */
  6. public class TuanZhanException implements ThrowsAdvice {
  7. //该方法会在露娜团战出现异常后自动执行
  8. public void afterThrowing(Method method, Object[] args,
  9. Object target, Exception ex){
  10. System.out.print(this.getClass().getName() + " -- ");
  11. Luna luna = new Luna();
  12. luna.run();
  13. }
  14. }

配置到spring-aop,xml:

  1. <bean id = 'TuanZhanException' class="com.spring.service.TuanZhanException"></bean>
  2. <!-- 定义一个切面 -->
  3. <aop:config>
  4. <!-- 定义所有可供露娜切入的点(方法) -->
  5. <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
  6. <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
  7. <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
  8. <aop:advisor advice-ref="AfterTuanZhan" pointcut-ref="pointcut"/>
  9. <aop:advisor advice-ref="TuanZhanException" pointcut-ref="pointcut"/>
  10. </aop:config>

现在,我们重新执行测试代码:

  1. ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
  2. Battle battle = (Battle)context.getBean("Battle");
  3. battle.tuan();

总结:

1. aop面向切面,切的是什么,没错,切的是方法!
2. 怎么切,你记好了,就是你先自己规定哪些方法需要切,然后设置切入的方式:方法执行之前做什么,执行之后做什么,如果方法出现异常,又要做什么?另外还有一种方法执行的过程中做什么,只是用的比较少,反正我还没有见过在哪里用了。用的最多的就是发生异常后做什么,比如事务管理。

据说露娜要重做,玩个屁,劳资退游吃鸡去了,谢谢。

如果喜欢我的文章,还请点一波关注,谢谢老铁!

源码链接:http://pan.baidu.com/s/1o8zHMqe 密码:om9i

【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?的更多相关文章

  1. 【Java框架型项目从入门到装逼】第一节 - Spring框架 IOC的丧心病狂解说

    大家好,好久不见,今天我们来一起学习一下关于Spring框架的IOC技术. 控制反转--Spring通过一种称作控制反转(IoC)的技术促进了松耦合.当应用了IoC,一个对象依赖的其它对象会通过被动的 ...

  2. 【Java框架型项目从入门到装逼】第十二节 项目分层

    这一节我们开始对项目进行分层,一般来说,一个web项目的层次结构如下图所示: controller层为我们的控制层,用来接收用户的请求,比如新增一个学生的信息,新增的请求最先就是走到这一层.contr ...

  3. 【Java框架型项目从入门到装逼】第七节 - 学生管理系统项目搭建

    本次的教程是打算用Spring,SpringMVC以及传统的jdbc技术来制作一个简单的增删改查项目,对用户信息进行增删改查,就这么简单. 1.新建项目 首先,打开eclipse,新建一个web项目. ...

  4. 【Java框架型项目从入门到装逼】第五节 - 在Servlet中接收和返回数据

    在上一节的程序中,我们可以看到HttpServletRequest, HttpServletResponse这两个对象.可以说,这是JavaWeb中至关重要的两个对象.接下来,我们来做一个简短的说明: ...

  5. 【Java框架型项目从入门到装逼】第三节 - 如何用Tomcat发布web项目?

    啥叫Tomcat?有道词典是这么说的. 这个我们姑且不管,实际上呢,Tomcat是一种Web服务器,我们自己做好了一个Web项目,就可以通过Tomcat来发布.服务器呢,又分为硬件服务器和软件服务器. ...

  6. 【Java框架型项目从入门到装逼】第四节 - 编写第一个Servlet程序

    在开始这一节之前呢,我们还需要把Tomcat配置到Eclipse中,配置的方式很简单,打开Eclipse,Window,Preferences,进入到这个页面: 将Tomcat的安装目录配置到Ecli ...

  7. 【Java框架型项目从入门到装逼】第九节 - 数据库建表和CRUD操作

    1.新建学生表 这节课我们来把和数据库以及jdbc相关的内容完成,首先,进行数据库建表.数据库呢,我们采用MySQL数据库,我们可以通过navcat之类的管理工具来轻松建表. 首先,我们得建一个数据库 ...

  8. 【Java框架型项目从入门到装逼】第十四节 查询用户列表展现到页面

    这一节,我们来实现一下用户列表搜索,最终的效果如下: 这边我们要使用easyUI给我们提供的datagrid组件. HTML结构如下 <!-- 数据列表 --> <table id= ...

  9. 【Java框架型项目从入门到装逼】第八节 - 用EasyUI绘制主界面

    1.引入资源包 在上一节中,我们把基本的框架都搭好了,用了Spring,SPringMVC.这一节,我们先来画页面,前端框架采用EasyUI来实现. easyui是一种基于jQuery的用户界面插件集 ...

  10. 【Java框架型项目从入门到装逼】第十三节 用户新增功能完结篇

    这一节,我们把用户新增的功能继续做一个完善.首先,新增成功后,需要给前台返回一个信息,就是告诉浏览器,这次用户新增的操作到底是成功了呢,还是失败了呢?为此,我们需要专门引入一个结果类,里面只有两个属性 ...

随机推荐

  1. C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  2. WPF 中的 Pack URI地(资源文件加载)

    参考资源网http://msdn.microsoft.com/zh-cn/library/aa970069.aspx#Absolute_vs_Relative_Pack_URIs 在 Windows ...

  3. Echarts数据可视化全解注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  4. Collection和Map的默认扩容参数

    初始大小:调用无参构造函数时默认的容量 加载因子:超过 (当前容量*加载因子) 时会进行扩容 扩容因子:扩容时增加的容量为 (当前容量*扩容因子)        容器         初始容量    ...

  5. SAP smartform 实现打印条形码

    先在SE73里定义一个新的BARCODE,注意一定要用新的才可以,旧的是打印不出来的. 然后定义一个SMARTFORM的样式,把你定义的BARCODE放到字符样式里面去. 再做SMARTFORM就可以 ...

  6. git无法pull仓库refusing to merge unrelated histories

    本文讲的是把git在最新2.9.2,合并pull两个不同的项目,出现的问题如何去解决fatal: refusing to merge unrelated histories 我在Github新建一个仓 ...

  7. android 统计启动时长,标准

    一.启动的类型 冷启 动,application没有被创建,需要先创建进程,然后启动MainActivity.由于这个过程需要fork一个新进程,所以耗时. 热启动,同上面对照,已经启动过applic ...

  8. Linux入门(3)——Ubuntu16.04下安装VMware

    下载linux版本 http://www.vmware.com/cn/products/workstation/workstation-evaluation.html 激活秘钥:5A02H-AU243 ...

  9. PHP二分查找算法

    思路:递归算法.在一个已经排好序的数组中查找某一个数值,每一次都先跟数组的中间元素进行比较,若相等则返回中间元素的位置,若小于中间元素,则在数组中小于中间元素的部分查找,若大于中间元素,则在数组中大于 ...

  10. 学习一门新语言需要了解的基础-12 if和switch对比

    本节内容 是否存在性能差异 使用场景 反汇编对比[付费阅读] 之前初步接触了汇编,然后利用汇编简单了解下函数调用的过程,包括怎么样保护堆栈帧现场和恢复现场.另外做了简单的函数调用参数复制,返回值的传递 ...