AOP实现之相关概念与准备工作(一)

来源:互联网 发布:无限极 树 mysql 编辑:程序博客网 时间:2024/06/07 20:19

在讲AOP的实现原理之前,我们有必要先来了解一下什么是Aop,这里我不会说它的众多概念,如果想了解术语概念可以去看其它的文章;


在网上或者各大书籍中都有关于AOP中各种概念的解释,比如 目标对象, 切面,配置,增强类,通知, 切点,通知器 ,代理  等等概念,我个人觉得没有必要来专研这些学术概念的具体意思,简单的讲,不就是通过一些手段,在调用我们想要调用的方法前后自动的去调用另外的方法么!


Aop(Aspect Oriented Programming)是面向切面编程的意思,我们平常进行代码开发就像下图中所示,按流程进行方法调用,而AOP就是在这个流程中,横切一刀进行方法调用,在这些方法中加入一些通用的业务逻辑处理,比如在调用Obj1对象的method2()方法前,我可以先调用obj3的before()开启一段事物,当方法调用完毕或,再调用after()方法进行事物提交,这整个过程对我们编程而言是透明的,所以达到了解耦以及代码复用的目的;


 那AOP到底是怎么做到在调用某个方法前自动的去调用另一个方法呢?答案就是动态代理, 由于我们使用了IOC容器来让spring为我们创建对象,那么spring完全可以为我们创建一个proxy对象,在创建代理对象时,spring完全可以在调用目标方法前后增加它的业务逻辑处理,至于增加了什么业务逻辑处理,它又是怎么读取解析我们的配置文件来创建proxy对象的,这些就是我们接下来要探讨的内容了!


在源码解析之前,我们必须得先将测试环境搭建好,OK,我们先来写点代码让环境跑起来!

/*** * 测试AOP的接口 * @author ying.cai * @email 919126624@qq.com * @version 1.0 */public interface AopTargetInterface {void show();}public class AopTargetInterfaceImpl implements AopTargetInterface{@Overridepublic void show() {System.out.println("AopTargetInterfaceImpl.show()");}}/*** * 增强类 * @author ying.cai * @email 919126624@qq.com * @version 1.0 */public class AopTargetAdvice {public void beforeInvoke(){System.out.println("AopTargetAdvice.beforeInvoke()");}public void afterInvoke(){System.out.println("AopTargetAdvice.afterInvoke()");}}/*** * AOP有几个主要概念 * 目标对象,切面,增强类, 配置,通知, 切点,通知器: * @author ying.cai * @email 919126624@qq.com * @version 1.0 */public class TestSpringAop {public static void main(String[] args) {//aopTargetInterfaceImpl实现了AopTargetInterface接口,spring为用JDK的动态代理为我们创建代理对象//如果没实现接口,则用cglib方式来创建代理对象,后面我们会详细了解这个过程!ApplicationContext app = new ClassPathXmlApplicationContext("testAop.xml");AopTargetInterface obj = (AopTargetInterface)app.getBean("aopTargetInterfaceImpl");obj.show();}}


<?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" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd" default-lazy-init="true"><!-- 目标对象1,实现了接口 --><bean id="aopTargetInterfaceImpl" class="com.fyrj.compoment.spring.test.AopTargetInterfaceImpl"/> <!-- 增强Advice --><bean id="aopTargetAdvice" class="com.fyrj.compoment.spring.test.AopTargetAdvice"/><!-- 配置切面 -->    <aop:config>          <aop:aspect ref="aopTargetAdvice">          <!-- 配置增强方法以及切入点 -->             <aop:before method="beforeInvoke" pointcut="execution(* *.show*(..))"/>               <aop:after method="afterInvoke" pointcut="execution(* *.*show*(..))"/>          </aop:aspect>      </aop:config></beans>

看一下输出:*****************************************************************************************

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

AopTargetAdvice.beforeInvoke()
AopTargetInterfaceImpl.show()
AopTargetAdvice.afterInvoke()

*******************************************************************************************************


OK,我们来稍作解释,aopTargetInterfaceImpl类就是目标对象因为我们想要调用的是它的方法,而配置则就是我们的xml文件,pointcut配置就是我们的切点了,它是一个表达式,定义了在调用目标对象的某某方法前或者后,需要先去调用增强类的增强方法,在这里,增强类就是AopTargetAdvice类,由于我们的表达式支持在调用任何类的任何show***方法前都先调用增强类的增强方法,所以aopTargetInterfaceImpl的show()方法在调用前后都会先调用增强方法,那么这个目标对象的show()方法就是我们的切面了 ,至于通知与通知器的概念,我们在后面再解析!


很简单吧,通过几行配置spring就帮我们完成了AOP的整个过程,接下来我们就要来解析这个过程是具体怎么来实现的了!


1 0