java面向切面编程总结-面向切面的本质
面向切面的本质:定义切面类并将切面类的功能织入到目标类中;
实现方式:将切面应用到目标对象从而创建一个新的代理对象的过程。替换;
使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Before, @AfterReturning,@After,@AfterThrowing,@Around).
https://www.cnblogs.com/oumyye/p/4480196.html
现将图6-6中涉及到的一些概念解释如下。
切面(Aspect):
其实就是共有功能的实现。如日志切面、权限切面、事务切面等。在实际应用中通常是一个存放共有功能实现的普通Java类,之所以能被AOP容器识别成切面,是在配置中指定的。
切面:织入类
@Aspect
public class MyAspect {}
通知(Advice):
是切面的具体实现。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际应用中通常是切面类中的一个方法,具体属于哪类通知,同样是在配置中指定的。
通知:织入类的事件;
@Aspect
@Component
public class LogInterceptor {
@Pointcut("execution(public * com.oumyye.service..*.add(..))")
public void myMethod(){};
/*@Before("execution(public void com.oumyye.dao.impl.UserDAOImpl.save(com.oumyye.model.User))")*/
@Before("myMethod()")
public void before() {
System.out.println("method staet");
}
@After("myMethod()")
public void after() {
System.out.println("method after");
}
@AfterReturning("execution(public * com.oumyye.dao..*.*(..))")
public void AfterReturning() {
System.out.println("method AfterReturning");
}
@AfterThrowing("execution(public * com.oumyye.dao..*.*(..))")
public void AfterThrowing() {
System.out.println("method AfterThrowing");
}
}
通知传递参数
在Spring AOP中,除了execution和bean指示符不能传递参数给通知方法,其他指示符都可以将匹配的方法相应参数或对象自动传递给通知方法。获取到匹配的方法参数后通过”argNames”属性指定参数名。如下,需要注意的是args(指示符)、argNames的参数名与before()方法中参数名 必须保持一致即param。
@Before(value="args(param)", argNames="param") //明确指定了
public void before(int param) {
System.out.println("param:" + param);
}
连接点(Joinpoint):
就是程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出或字段修改等,但Spring只支持方法级的连接点。
连接点:目标类+目标函数;用于切面类在运行时获取目标对象+函数+参量上下文信息;
@Around("execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
}
切入点(Pointcut):
用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。
切入点:在哪里(什么样函数)织入;用于在切面中注解织入到哪些范围的哪些函数上;
定义过滤切入点函数时,直接把execution以定义匹配表达式作为值传递给通知类型的如下:
@After(value="execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..))")
public void after(){
System.out.println("最终通知....");
}
采用与ApectJ中使用pointcut关键字类似的方式定义切入点表达式如下,使用@Pointcut注解:
@Pointcut("execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..))")
private void myPointcut(){}
@After(value="myPointcut()")
public void afterDemo(){
System.out.println("最终通知....");
}
切入点指示符
为了方法通知应用到相应过滤的目标方法上,SpringAOP提供了匹配表达式,这些表达式也叫切入点指示符,在前面的案例中,它们已多次出现。
通配符
在定义匹配表达式时,通配符几乎随处可见,如*、.. 、+ ,它们的含义如下:
- .. :匹配方法定义中的任意数量的参数,此外还匹配类定义中的任意数量包
//任意返回值,任意名称,任意参数的公共方法 - execution(public * *(..))
- //匹配com.zejian.dao包及其子包中所有类中的所有方法
- within(com.zejian.dao..*)
- + :匹配给定类的任意子类
//DaoUserwithin(com.zejian.dao.DaoUser+) - * :匹配任意数量的字符
匹配包及其子包中所有类的所有方法 - within(com.zejian.service..*)
- //匹配以set开头,参数为int类型,任意返回值的方法
- execution(* set*(int))
execution 用于匹配方法执行的连接点;
within 用于匹配指定类型内的方法执行;
目标对象(Target):
就是那些即将切入切面的对象,也就是那些被通知的对象。这些对象中已经只剩下干干净净的核心业务逻辑代码了,所有的共有功能代码等待AOP容器的切入。
目标对象:目标类
<!-- 定义目标对象 -->
<bean id="userDaos" class="com.zejian.spring.springAop.dao.daoimp.UserDaoImp" />
代理对象(Proxy):
将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。
代理对象:目标类织入切面功能后的中间层(类)
织入(Weaving):
将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译期、类装载期及运行期,当然不同的发生点有着不同的前提条件。譬如发生在编译期的话,就要求有一个支持这种AOP实现的特殊编译器;发生在类装载期,就要求有一个支持AOP实现的特殊类装载器;只有发生在运行期,则可直接通过Java语言的反射机制与动态代理机制来动态实现。
织入:织入的实现方式;
https://blog.csdn.net/liujiahan629629/article/details/18864211
基于XML的开发
前面分析完基于注解支持的开发是日常应用中最常见的,即使如此我们还是有必要了解一下基于xml形式的Spring AOP开发,这里会以一个案例的形式对xml的开发形式进行简要分析,定义一个切面类
/**
* Created by zejian on 2017/2/20.*/
public class MyAspectXML {
public void before(){
System.out.println("MyAspectXML====前置通知");
}
public void afterReturn(Object returnVal){
System.out.println("后置通知-->返回值:"+returnVal);
}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("MyAspectXML=====环绕通知前");
Object object= joinPoint.proceed();
System.out.println("MyAspectXML=====环绕通知后");
return object;
}
public void afterThrowing(Throwable throwable){
System.out.println("MyAspectXML======异常通知:"+ throwable.getMessage());
}
public void after(){
System.out.println("MyAspectXML=====最终通知..来了");
}
}
通过配置文件的方式声明如下(spring-aspectj-xml.xml):
<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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--<context:component-scan base-package=""-->
<!-- 定义目标对象 -->
<bean name="productDao" class="com.zejian.spring.springAop.dao.daoimp.ProductDaoImpl" />
<!-- 定义切面 -->
<bean name="myAspectXML" class="com.zejian.spring.springAop.AspectJ.MyAspectXML" />
<!-- 配置AOP 切面 -->
<aop:config>
<!-- 定义切点函数 -->
<aop:pointcut id="pointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.add(..))" />
<!-- 定义其他切点函数 -->
<aop:pointcut id="delPointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.delete(..))" />
<!-- 定义通知 order 定义优先级,值越小优先级越大-->
<aop:aspect ref="myAspectXML" order="0">
<!-- 定义通知
method 指定通知方法名,必须与MyAspectXML中的相同
pointcut 指定切点函数
-->
<aop:before method="before" pointcut-ref="pointcut" />
<!-- 后置通知 returning="returnVal" 定义返回值 必须与类中声明的名称一样-->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="returnVal" />
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut" />
<!--异常通知 throwing="throwable" 指定异常通知错误信息变量,必须与类中声明的名称一样-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="throwable"/>
<!--
method : 通知的方法(最终通知)
pointcut-ref : 通知应用到的切点方法
-->
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
beans
声明方式和定义方式在代码中已很清晰了,了解一下即可,在实际开发中,会更倾向与使用注解的方式开发
https://www.cnblogs.com/junzi2099/p/8274813.html
java面向切面编程总结-面向切面的本质的更多相关文章
- 重新学习之spring第二个程序,配置AOP面向切面编程
第一步:在配置好的ioc容器的基础上,导入面向切面编程所需要的jar包 (本案例用的是spring3.2.4,由于spring3.2.4的官网jar包中不再有依赖包,所以依赖包都是从网上找的) 第二步 ...
- AOP面向方面(切面)编程
1.引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创建和管理的模块.于是出现了以系统模块化特性的面向对象程序设计技术.模块化的面向对象编程极度极地提 ...
- 杂项-编程:AOP(面向切面编程)
ylbtech-杂项-编程:AOP(面向切面编程) 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一 ...
- 【转】 AOP(面向切面编程)、Filter(过虑器)、Interceptor(拦截器)
AOP(面向切面编程) 面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承.多态和封装.而封装就要求将功能分散到不同的对象中去,这在软 ...
- 03-spring框架—— AOP 面向切面编程
3.1 动态代理 动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由 JVM 根据反射等机制动态生成的.代理对象与目标 ...
- 如何通俗的理解spring的控制反转、依赖注入、面向切面编程等等
之前一直不理解spring的一些基础特性是什么意思,虽然网上的解释也很多,但是由于我比较笨,就是看不懂,知道最近才稍微了解,下面就以通俗讲解的方式记录下来. 前言 假设我是一个没有开店经验的小老板,准 ...
- 面向切面编程--AOP(转)
add by zhj:面向切面编程就是在不修改函数A的前提下,在函数A前后插入业务逻辑B, C, D...这其实算是功能分解,将大模块S=A+B+C+D+……分解为独立的小功能A,B,C,D……,模块 ...
- Spring实战Day7面向切面编程术语介绍
#### 面向切面编程 为什么需要切面? 有些功能需要在应用中的多个地方使用到,但是我们又不想在着每个地方都调用他们 切面术语 通知(advice):切面需要完成的工作 通知的类型(什么时间完成工作) ...
- Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】
According to wikipedia aspect-oriented programming (AOP) is a programming paradigm that aims to inc ...
随机推荐
- Java学习-jsp内置对象Session
- iOS开发常用函数
1. 三角函数 double sin (double); 正弦 double cos (double);余弦 double tan (double);正切 2 .反三角函数 double asin ...
- javax.naming.NamingException: Cannot create resource instance报错修改
//下面内容为网上获取 avax.naming.NamingException: Cannot create resource instance at org.apache.naming.factor ...
- 推荐 VSCode 上特别好用的 Vue 插件 - vetur
作者 @octref 此前 V2EX 发过帖子,最近新增代码补全功能,综合比较应该是目前 VSCode 上面最好用的 Vue 插件. 能够实现在 .vue 文件中: 语法错误检查,包括 CSS/SCS ...
- javascript中让你捉摸不定的this
this到底指向谁,估计很多人在使用javascript的过程中都遇到过,这个关键字如果没搞懂,在一些高级功能中都会困难重重,搜了下相关文章,介绍的都挺多的,也有很深入的,比如汤姆大叔的<深入理 ...
- Android ListView的XML属性
1.ListView的XML属性 android:divider //在列表条目之间显示的drawable或color android:dividerHeight //用来指定divider的高度 a ...
- J2EE开发环境--RAP
J2EE开发环境--RAP J2EE开发环境分四步: 1.JDK环境 2.tomcat 3.redis环境 4.mysql环境 5.RAP包 线上环境,推荐使用源码,自建应用用户,设置对应规则,禁止关 ...
- ubuntu-15.04-desktop-amd64想要安装KDE桌面,结果出现如下问题
The following packages have unmet dependencies: kubuntu-desktop : Depends: ark but it is not going t ...
- 用 Core Animation 实现图片的碎片化
用 Core Animation 实现图片的碎片化 参考书籍: 效果如下: 原理其实非常简单哦:). 1. 创建一个CALayer,使用其 contents 属性来装载一张图片(获取图片的CGImag ...
- 使用截图工具FastStone Capture
使用截图工具FastStone Capture -谨以此教程献给某位上进的测试人员- FastStone Capture是本人用过的windows平台上最好用的截图工具,界面简洁,功能强大,还支持屏幕 ...