深入理解Spring AOP
来源:互联网 发布:用java开发apk的步骤 编辑:程序博客网 时间:2024/04/30 17:26
一、AOP的概念
AOP(Aspect Oriented Programming),意思是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的技术。使用AOP技术,可以将一些与系统相关的业务逻辑功能模块,提取出来,独立实现,然后通过切面切入进系统。从而避免了在核心业务逻辑的代码中混入很多的系统相关的逻辑——比如事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等等。
二、AOP的实现原理是什么
AOP主要是通过代理模式来实现,主要分为JDK动态代理和CGLib动态代理。下面我们的详细了解一下这两种代理模式的原理。
1、JDK动态代理
JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。
nvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。
Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
下面是JDK动态代理的类图:
根据上面的类图 ,下面我们通过一个查看员工工资系统的示例代码了解JDK的动态代理。在工资系统中业务逻辑包括。查看员工工资、系统安全、操作权限和日志管理。其中主要核心业务逻辑是查看员工的工资。
1. 查看员工工资
//定义的SalaryManager接口public interface SalaryManager { public void showSalary();}//接口SalaryManager的具体实现类public class SalaryManagerImpl implements SalaryManager{ public void showSalary() { System.out.println("show salary"); }}
2. 系统安全
public class Security { public void security(){ System.out.println("security"); }}
3.操作权限
public class Privilege { private String access; public String getAccess() { return access; } public void setAccess(String access) { this.access = access; }}
4.日志管理
public class Logger { public void logging(){ System.out.println("logging"); }}
5.实现InvocationHandler接口,将所有的业务逻辑组合在一起
public class MyInterceptor implements InvocationHandler{ private Object target; private Logger logger; private Security security; private Privilege privilege; public MyInterceptor(Object target, Logger logger, Security security, Privilege privilege) { super(); this.target = target; this.logger = logger; this.security = security; this.privilege = privilege; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /** * 1、启动日志 * 2、启动安全性的类 * 3、验证权限 * 调用目标对象的目标方法 */ this.logger.logging(); this.security.security(); if("admin".equals(this.privilege.getAccess())){ method.invoke(target);//动态调用目标方法 }else{ System.out.println("没有权限查看工资"); } return null; }}
6.使用Proxy接口 ,生成目标类的代理对象
public class SalaryTest { @Test public void testSalary(){ Object target = new SalaryManagerImpl(); Logger logger = new Logger(); Security security = new Security(); Privilege privilege = new Privilege(); privilege.setAccess("asfd"); MyInterceptor interceptor = new MyInterceptor(target, logger, security, privilege); SalaryManager proxy = (SalaryManager)Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); proxy.showSalary(); }}
2、CGLib动态代理
CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。
(备注:其代码演示就不在此赘述)
3、JDK和CGLib动态代理区别
JDK和CGLib动态代理区别主要体现在以下两点
JDK动态代理只能对实现了接口的类生成代理,而不能针对类
CGLIB是针对类实现代理,生成代理类是目标类的子类
备注:在Spring中对于AOP代理类的生成原则是:
如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;
如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类
三、在Spring中AOP的配置方式
首先,我们结合上述查看员工工资的系统实例代码来看一下,AOP中的一些重要概念
- 切面(Aspect):就是除了核心关注点之外所有操作。例如 : Security ,Privilege 类就是切面。“切面”在ApplicationContext中来配置。
- 连接点(Joinpoint) :目标类的中方法 。例如SalaryManager中的 showSalary()方法。
- 通知(Advice) :“切面”对于某个“连接点”所产生的动作,其实,就是切面中方法。例如:Security 类中security()方法。
- 切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。就相当于条件判断语句。例如:在上述testSalary 中 if(“admin”.equals(this.privilege.getAccess()))而在 都由切入点表达式execution(* com.spring.service..(..))来决定
Spring中AOP实现在XML中的配置方式示例:
<tx:advice transaction-manager="transationManager" id="tx"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.ywendeng.ecs.service.*.*(..))" id="perfrom"/> <aop:advisor advice-ref="tx" pointcut-ref="perfrom"/> </aop:config>
- 深入理解Spring AOP
- 深入理解Spring AOP代理
- 深入理解Spring AOP之基本概念
- 深入理解Spring AOP之基本概念
- 深入理解Spring AOP实战(基于注解)
- 深入理解Spring AOP实战(基于XML)
- 深入理解Spring AOP之二代理对象生成
- Spring AOP深入理解之拦截器调用
- 深入理解面向切面的编程AOP、AspectJ、Spring
- Spring 框架入门helloworld实例-------深入理解IOC、AOP
- 深入理解Spring 之 源码剖析AOP(注解方式)
- Aop的深入理解
- 深入理解 String AOP
- 深入理解sping AOP
- Android 深入理解AOP
- 深入Spring AOP技术研究
- Spring AOP 深入剖析
- Spring AOP 深入剖析
- ERROR! The server quit without updating PID file (/var/lib/mysql/service.pid).
- 持续交付之六——构建与部署的脚本化
- Linux下 nginx + php 环境搭建
- android之wifi开发(一)
- chrome源码分析1:content模型
- 深入理解Spring AOP
- iOS - 摇一摇
- 康拓展开
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
- 简单的http过滤模块
- Android 高清加载巨图方案 拒绝压缩图片
- 实战Nginx与PHP(FastCGI)的安装、配置与优化
- java基础知识(标识符,命名规则,注释)
- Java四种生成xml文件的方法