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

原文地址:https://www.cnblogs.com/feng9exe/p/10364516.html

时间: 2024-11-10 15:20:38

java面向切面编程总结-面向切面的本质的相关文章

面向对象编程、面向组件编程、面向方面编程、面向服务编程

1.什么是面向对象编程(Object-Oriented Programming)? 面向对象编程 (Object-Oriented Programming)简称OOP技术,是开发计算机应用程序的一种新方法.新思想.过去的面向过程编程常常会导致所有的代码都包含在几个模块中,使程 序难以阅读和维护.在做一些修改时常常牵一动百,使以后的开发和维护难以为继.而使用OOP技术,常常要使用许多代码模块,每个模块都只提供特定的功能, 它们是彼此独立的,这样就增大了代码重用的几率,更加有利于软件的开发.维护和升

面向“接口”编程和面向“实现”编程

来自http://www.vaikan.com/program-to-an-interface-fool/ 面向'接口'编程,而不是面向'实现'. 这是什么意思? 首先我们需要理解什么是'接口',什么是'实现'.简言之,一个接口就是我们要调用的一系列方法的集合,有对象将会响应这些方法调用. 一个实现就是为接口存放代码和逻辑的地方. 本质上讲,这个原则倡导的是,当我们写一个函数或一个方法时,我们应该引用相应的接口,而不是具体的实现类. 面向'实现'编程 首先我们看看,如果不遵循这个原则会发生什么.

AOP面向方面(切面)编程

1.引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创建和管理的模块.于是出现了以系统模块化特性的面向对象程序设计技术.模块化的面向对象编程极度极地提高了软件系统的可读性.复用性和可扩展性.向对象方法的焦点在于选择对象作为模块的主要单元,并将对象与系统的所有行为联系起来.对象成为问题领域和计算过程的主要元素.但面向对象技术并没有从本质上解决软件系统的可复用性.创建软件系统时,现实问题中存在着许多横切关注点,比如安全性检查.日志记录.性能监控,异常

AOP (面向切面编程)

AOP (面向切面编程) 编辑 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. AOP在其他领域也有其他含义.[1] 中文名 面向切面编程 外文

重新学习之spring第二个程序,配置AOP面向切面编程

第一步:在配置好的ioc容器的基础上,导入面向切面编程所需要的jar包 (本案例用的是spring3.2.4,由于spring3.2.4的官网jar包中不再有依赖包,所以依赖包都是从网上找的) 第二步:配置applicationContext.xml(包括ioc对象配置,以及面向切面编程的相关配置) 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.sp

03-spring框架—— AOP 面向切面编程

3.1 动态代理 动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由 JVM 根据反射等机制动态生成的.代理对象与目标对象的代理关系在程序运行时才确立. 3.1.1 JDK 动态代理的实现方式常用的有两种:使用 JDK 的 Proxy,与通过 CGLIB 生成代理.Jdk 的动态要求目标对象必须实现接口,这是 java 设计上的要求. 从 jdk1.3 以来,java 语言通过 java.lang.reflect

面向未来编程

我们一直以来都知道面向对象编程,面向过程编程.大多数时候还是面向工资编程,面向生活编程.面向任务编程,面向公司编程,面向领导编程. 工资不给力,心里认为委屈:生活有压力.影响工作情绪.任务完毕就好,应付一下咯.都是公司的事儿,完毕了就拉倒吧.领导喜欢什么体位就按什么体位来搞喽. 这样导致的结果呢,宝宝有苦可是不说. 工作不开心,压力大.状态不好就导致项目代码不好.文档不够,设计不行,项目管理混乱,对上都是敷衍,对下都是放羊,里外都没有交代. 实际上,我们首先应该是面向自己编程,然后是面向团队编程

多态的支撑系统:面向多态编程

面向多态编程是面向抽象编程: 多态的本质是抽象: 一.多态的分类: 1.由函数到方法,隐藏缺省参量从而实现抽象:面向接口与继承: 2.泛型:参量化类型抽象出共同的结构和行为: 3.高阶函数:抽象出共同的基础操作: 4.运行时类型信息: 二.多态的支持系统分为两类: 1.类型支持: 2.函数调用的解释支持: 三.类型支持 语言层面的支持: 接口.继承.泛型.运行时类型信息 编程语言提供的抽象关键字 https://www.cnblogs.com/feng9exe/p/9876045.html 内存

Java实战之03Spring-03Spring的核心之AOP(Aspect Oriented Programming 面向切面编程)

三.Spring的核心之AOP(Aspect Oriented Programming 面向切面编程) 1.AOP概念及原理 1.1.什么是AOP OOP:Object Oriented Programming面向对象编程 AOP:Aspect Oriented Programming面向切面编程 1.2.代理 充分理解:间接 主要作用:拦截被代理对象执行的方法,同时对方法进行增强. 1.2.1.静态代理 特点:代理类是一个真实存在的类.装饰者模式就是静态代理的一种体现形式. 1.2.2.动态代