spring开发aop应用有三种方法:
一:Spring 1.2版本中通过ProxyFactoryBean来实现aop,即通过动态代理来实现的,Aspect必须继承MethodBeforeAdvice,MethodAfterAdvice等
<!--被代理的对象-->
<bean id="man" class="Man">
<property name="name">
<value type="java.lang.String">张三</value>
</property>
</bean>
<!--继承了MethodBeforeAdvice类的 Aspect->
<bean id="fbi" class="FBI" />
<bean id="civilian"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="man" />
</property>
<property name="interceptorNames">
<list>
<value>fbi</value>
</list>
</property>
</bean>
二:Spring 2.0 AOP 应用
需要改的是FBI 这个类,而且它也不需要再实现某些接口了
public class FBI {
public void before(JoinPoint point){
Man man = (Man)point.getTarget();
System.err.println("FBI 发现" + man.getName() + "正在进行 " +
point.getSignature().getName() + " 活动。");
}
}
注意这个类里面的方法 before(JoinPoint),方法名可以是任意的,可以带一个JoinPoint 类
型的参数,也可以不带参数直接写成before(),但是这个连接点(JoinPoint)对象带来了所
有和这次方法调用有关的信息,包括方法参数,目标对象等等,所以一般要做日志记录的话
会带上它。
接下来是测试类的代码,和以前的几乎没有任何不同,只不过现在直接访问的是man
这个bean。
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="fbi" class="FBI" />
<bean id="man" class="Man">
<property name="name">
<value type="java.lang.String">张三</value>
</property>
</bean>
<aop:config>
<aop:pointcut id="manPointcut"
expression="execution(* Man.*(..))" />
<aop:aspect id="beforeExample" ref="fbi">
<aop:before pointcut-ref="manPointcut" method="before" />
</aop:aspect>
</aop:config>
</beans>
1. 配置文件的开头加入了aop 命名空间,如代码中粗斜体所示。
2. 使用aop:config 标签来定义AOP,不是使用ProxyFactoryBean 来定义一个新的
bean。
一个是人的对象,另
一个则是联邦调查局的探员。而aop:config 中定义了所有的AOP 设置信息。aop:pointcut
定义了一个切入点,id 给出了这个切入点的唯一名字,而expression 定义了切入点的表达
式,那么这个定义到底表示了什么信息呢?它的意思是表示一种场景,即执行(execution)
Man 对象的所有方法的这种情况,这就是表达式execution(* Man.*(..))的意义所在,
Man.*(..)表示Man 类的所有方法。接下来呢,需要定义一个切面,用aop:aspect 来定义,
它的ref 属性指定了这个切面所对应的bean 定义的id,这里指向fbi 这个bean 类;子标签
aop:before 则指示了当发生了名为manPointcut 的切入点(情况)前(用pointcut-ref 属性
指定,pointcut-ref=”manPointcut”),就调用名为before 的方法,这个方法位于aspect 里
面的引用的那个bean 中,这里是fbi(即ref=”fbi”)。其实Spring 执行到这里后,会自动的
把这些代码翻译成底层的Bean 定义(后台依然会采用ProxyFactoryBean 这样的机制),
然后把对应的获取bean 的操作直接委托给代理类,这就是为什么上文提到的测试类只需要
访问原来的man 这个bean,对应的拦截类就会被执行的原因。从这里看到Spring 2.0 中要
定义一个AOP 的bean 类,仍然是比较复杂的,XML 文件和概念都增加了很多,需要读者
慢慢来学习和理解。
三使用标注(@AspectJ)实现AOP
的一个库来做切点(pointcut)解析和匹配。
为了在Spring 配置中使用@AspectJ aspects,你必须首先启用Spring 对基于@AspectJ
aspects 的配置支持,自动代理(autoproxying)基于通知是否来自这些切面。 自动代理是
指Spring 会判断一个bean 是否使用了一个或多个切面通知,并据此自动生成相应的代理
以拦截其方法调用,并且确认通知是否如期进行。
通过在你的Spring 的配置文件中引入下列元素来启用Spring 对@AspectJ 的支持:
<aop:aspectj-autoproxy/>
也可以通过在你的application context 中添加如下定义来启用@AspectJ 支持:
<bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyC
reator" />
你需要在你的应用程序的classpath 中引入两个AspectJ 库:aspectjweaver.jar 和
aspectjrt.jar。我们这里用的MyEclipse,在添加Spring 开发功能时已经自动的加入了这些
类库文件,无需手工配置了。
定义切面Aspect:在启用@AspectJ 支持的情况下,在application context 中定义的任意带有一个@Aspect 切面(拥有@Aspect 标注)的bean 都将被Spring 自动识别并用于
配置在Spring AOP。
定义切入点Pointcut:现在通过在 @AspectJ 标注风格的 AOP 中,一个切入点签名
通过一个普通的方法定义来提供,并且切入点表达式使用 @Pointcut 标注来表示(作为切
入点签名的方法必须返回 void 类型)。代码可以参考清单10.12。
好了,引用了这么些文档,我们需要介绍这个基于标注的新的AOP项目了,这个项目
的名字是Spring2_0AOPAspectJ,如前一节所示加入了Spring核心和AOP类库后,就可以
开发了。那么相比较10.4.1 使用aop 标签实现AOP一节,这一个项目的代码仅仅有两个地
方要改。首先我们要修改FBI类的源码,加入标注来实现切面和切入点定义,如下所示:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 联邦调查局的探员将您的所有行动都记录在案。
* @author BeanSoft
*/
@Aspect
public class FBI {
@Before("execution(* Man.*(..))")
public void before(JoinPoint point){
Man man = (Man)point.getTarget();
System.err.println("FBI 发现" + man.getName() + "正在进行 " +
point.getSignature().getName() + " 活动。");
}
}
清单10.12 加入了Aspect 标注的FBI 类
这个类中的@Before 后面的"execution(* Man.*(..))"是切入点所对应的切入点点表达式,其意
义和上一节的是一致的,仍然表示的是执行 Man 类的所有方法时将触发此方法的执行。
使用了这种写法后,XML 配置文件将大大简化,其内容如下所示:
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy/><bean id="fbi" class="FBI" />
<bean id="man" class="Man">
<property name="name">
<value type="java.lang.String">张三</value>
</property>
</bean>
</beans>
1. 加入了粗斜体的<aop:aspectj-autoproxy/>定义;
2. 去掉了<aop:config>标签部分。
可以看到使用这种方式后,AOP 的开发和配置变的极其简单。这就是JDK 1.5 引入标注开
发后带来的好处。当然弱点嘛,那就是要修改配置必须重新编译源代码了。
注意:在这里你不能去掉<bean id="fbi" class="FBI" />这一个bean的定义,否
则自动AOP代理对象就没有机会被创建并工作了,那样的话man对象被代理也就无从谈起
了。
四开发环绕通知(Around Advice)AOP 应用
@Aspect
public class FBI {
@Around("execution(* Man.*(..))")
public Object before(ProceedingJoinPoint point) throws Throwable {
Man man = (Man)point.getTarget();
System.err.println("FBI 发现" + man.getName() + "即将正在进行 " +
point.getSignature().getName() + " 活动。");
// 禁止张三泡MM
if(point.getSignature().getName().equals("mm")) {
System.err.println("FBI 将阻止 " + man.getName() + " 泡MM。");
} else if(point.getSignature().getName().equals("sayHelp")) {
System.err.println("FBI 将欺骗 " + man.getName() + " 的朋友告
诉他们他很好。");
return "我是 " + man.getName() + " ,我现在过的很好。";
} else {Object object = point.proceed();
System.err.println("FBI 发现" + man.getName() + "已经完成了 " +
point.getSignature().getName() + " 活动。");
return object;
}
return null;
}
}
现在张三不光是不能泡MM 了,当他求救的时候,FBI 还可以直接拦截并修改,将其请求的
信息“救我,我是张三!”改成“我是张三,我现在过的很好。”,这样通过欺骗行为,张三
的朋友永远也不知道发生了什么事。
/**
* 具有聊QQ和泡MM以及求救三个行为的人对象,还有一个用户名属性。
* @author BeanSoft
*/
public class Man {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void qq() {
System.out.println("我在聊QQ");
}
public void mm() {
System.out.println("我在泡MM");
}
public String sayHelp() {
return "救我,我是" + getName();
}
}
分享到:
相关推荐
Spring AOP支持三种织入方式:编译时织入、加载时织入和运行时织入。Spring默认使用运行时织入,通过动态代理实现。 6. **代理(Proxy)**:代理是AOP的核心,它是目标对象的增强版本,负责在调用目标方法前后执行...
SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...
**Spring AOP应用Demo** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要模块,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个Demo是针对Spring AOP的...
通过上述步骤,你可以创建一个简单的Spring AOP应用,实现对特定方法的调用进行日志记录。当然,AOP的潜力远不止于此,你可以根据实际场景扩展通知类型,或者创建更复杂的切入点表达式,以实现更细粒度的控制。 在...
1. 注解驱动的AOP:这是最常用的实现方式,通过在方法上添加注解(如`@Before`, `@After`, `@Around`, `@AfterReturning`, `@AfterThrowing`)来定义通知,并使用`@Aspect`注解定义切面。 2. XML配置驱动的AOP:...
总的来说,Spring AOP提供了一种优雅的方式来管理横切关注点,使代码更整洁,降低了模块间的耦合。在实际开发中,它可以用于日志记录、权限控制、事务管理等多个场景,极大地提高了代码的可维护性和复用性。
2. **Spring AOP实现方式**:Spring提供了两种AOP实现,一种是基于代理(Proxy-based AOP),另一种是基于ASM字节码操作的AspectJ。基于代理的方式简单易用,而AspectJ则更为强大,支持更复杂的切面定义。 3. **...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种强大的方式来实现横切关注点,如日志、事务管理、安全性等,从而使得代码更加模块化和可维护。在本示例中,"springaop.zip" 包含了一个使用XML...
标题中的“API 线索图”可能意味着本文将通过一种图解的方式,即流程图或者类图的形式,来阐述Spring AOP的编程思想和API的使用。 描述中,“小马哥讲 Spring AOP 编程思想”表明这是由一位专家小马哥讲解的内容,...
在SpringAOP中,有几个关键的概念: 1. 连接点(Joinpoint)是指程序执行中的某个特定位置,如方法的调用前后、抛出异常后。在Spring中,仅支持方法作为连接点。 2. 切点(Pointcut)是用于匹配连接点的表达式,它...
除了`@Before`,Spring还提供了其他几种通知类型: 1. `@After` - 后置通知,无论方法是否抛出异常都会执行。 2. `@AfterReturning` - 返回后通知,只在方法正常返回时执行。 3. `@AfterThrowing` - 异常后通知,当...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理等。在本主题中,我们将深入探讨Spring AOP的注解版,它是基于Java注解的...
Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它为Java应用程序提供了声明式事务管理、日志记录、安全控制等跨切面关注点的功能。AOP允许开发者将一些通用功能如日志...
总的来说,Spring AOP通过XML配置为我们提供了一种灵活的方式来管理横切关注点,使我们的代码更加模块化和可维护。通过定义Advisor、切点和通知,我们可以将如日志记录、事务处理等通用功能轻松地插入到业务逻辑中,...
Spring AOP通过两种主要实现方式提供切面功能:代理模式(Proxy)和基于注解的切面(Annotation-based AOP)。代理模式下,Spring创建一个目标对象的代理,当调用目标方法时,代理会在前后添加额外的行为。而注解...
标题 "springaop" 暗示我们关注的是Spring框架中的AOP(面向切面编程)模块。在Spring框架中,AOP是一种强大的工具,它允许程序员定义“切面”,这些切面可以封装横切关注点,如日志、事务管理、性能监控等,将它们...
在Spring中实现AOP,一般有两种方式: - **基于接口的动态代理**:如果目标类实现了接口,Spring会使用JDK的动态代理机制,生成一个实现了相同接口的代理类,代理类在调用实际方法前/后执行通知。 - **基于类的...
Spring AOP提供了两种主要的应用方式: 1. **XML配置**:需要在Spring配置文件中声明切入点、通知类型和代理策略。例如,定义一个切入点表达式,然后配置通知,将通知应用到对应的连接点上。 ```xml <aop:config> ...
它提供了一种声明式的 AOP 实现方式,允许开发者使用注解或 XML 配置来定义切面、通知和切点。 在 Spring 中使用 AspectJ 需要进行以下配置: 1. **启用 AspectJ 注解支持**:为了在 Spring 应用中使用 AspectJ ...
总的来说,Spring AOP通过提供一种声明式的AOP实现,极大地简化了面向切面编程,使开发者能够更加专注于业务逻辑,而不是分散注意力去处理横切关注点。结合AspectJ库的使用,Spring AOP为现代企业级应用提供了强大的...