Spring笔记:AOP基础
引入AOP
SpringIOC相对而言还是比较容易理解的,它是反射技术实现的。SpringAOP,最大的用处是事务的控制,这是最麻烦也是最难理解的东西。
SpringAOP是通过动态代理来实现的。首先在传统MVC架构中,业务层一般都夹带着数据库的事务管理,例如,插入一个角色,它是使用RoleService接口的实现类RoleServerImpl来实现的。
当程序进入到insertRole方法的时候,Spring就会读取配置的传播行为进行设置,这里的配置为Propagation.REQUIRED,它的意思是当前方法如果有事务则加入当前事务,否则就创建新的事务。这样这个insertRole方法就在事务内调用了,那么它是怎么实现的呢?
我们不去描述太过抽象的概念,如切面、连接点、通知、切入点、目标对象、AOP代理等极其抽象的概念,而是从使用原理去讨论他们。
动态代理
SpringAOP是动态代理的典范,我们需要先熟悉一下动态代理的相关概念。
Mybatis中,Mapper仅仅是一个接口,而不是一个包含逻辑的实现类,我们知道一个接口是无法去执行的,那么它是如何运行的呢?这不是违反了教科书所说的接口不能运行的道理吗?
答案就是动态代理,不妨先来看一下Mapper到底是什么东西
很显然Mapper产生了代理类,这个代理类是MyBatis为我们创建。
代理模式
所谓的代理模式就是在原有的服务上多加了一个占位,通过这个占位去控制服务的访问。
举例子,假设你是一个公司的工程师,能提供一些技术服务,公司的客服是一个美女,他不懂技术。而我是一个客户,徐你们公司提供技术服务。显然,我只会找你们公司的客服,和客服沟通,而不是找你沟通。客服会根据公司的规章制度和业务规则来决定找不找你服务。那么此时客服就等同于你的代理,她通过和我的交流来控制对你的访问,当然他也可以提供一些你们公司对外的服务。而我只能通知他的代理访问你。对我而言,我跟本不需要认识你,只需要认识客服就可以了。事实上,站在我的角度,我会认为客服就是代表你们公司,而不管真正为我服务的你是怎么样的。
其次,为什么要用代理模式呢?通过代理可以控制如何访问真正的服务对象,提供额外的服务。另外有机会通过重写一些类来满足特定的需要,正如客服也可以根据公司的业务规则,提供一些服务,这个时候就不需要你劳你大驾了。
一般来说,代理分为两种,一种是JDK反射机制提供的代理,另一种是CGLIB代理。
JDK动态代理
JDK的动态代理,是由JDK的Java.lang.reflect包提供支持的,我们需要完成几个步骤:
- 编写服务类和接口,这个是真正的服务提供者,在JDK代理中接口是必须的。
- 编写代理类,提供绑定和代理方法。
JDK最大的缺点就是需要提供接口,而MyBatis的Mapper就是一个接口它采用的就是JDK的动态代理。我们先给一个服务接口。
public interface HelloService{ public void sayHello(String name); }
然后,写一个实现类
public class HelloServiceImpl implements HelloService{ public void sayHello(String name) { System.out.println("Hello"+name); } }
现在我们写一个代理类,提供真实对象的绑定和代理方法。代理类的要求是实现InvocationHandler接口的代理方法。