转载地址:http://blog.csdn.net/mawujun1234/archive/2008/04/22/2314190.aspx
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();
}
}
分享到:
相关推荐
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
Spring中实现AOP有很多方式,这里总结了四种,有基于代理的实现方式,也有基于AspectJ 的注解方式,还有基于AOP标签的配置
Spring实现AOP的4种方式
使用Spring的注解方式实现AOP的细节
spring aop demo 通过注解和配置文件的两种实现方式 包含jar包 下载直接运行
AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
NULL 博文链接:https://zhang-yingjie-qq-com.iteye.com/blog/319927
spring aop jar 包
springboot spring aop 拦截器 注解方式实现脱敏(涉及到:pom.xml -->application.properties --->启动类-->拦截器)
里面包括4个例子:(1)Spring实现AOP方式之一:基于XML配置的Spring AOP (2)Spring实现AOP方式之二:使用注解配置 Spring AOP (3)Spring AOP : AspectJ Pointcut 切点 (4)Spring AOP : Advice 声明 (通知注解)
死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序
Spring AOP的实现机制中文版,动态代理及原理,自定义类加载器
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
配置可以通过xml文件来进行,大概有四种方式: 1. 配置ProxyFactoryBean,显式地设置advisors, advice, target等(基于代理的AOP ) 2. 配置AutoProxyCreator,这种方式下,还是如以前一样使用定义的bean,但是从...
里面包含了多种Spring AOP配置,十分详细。
一个基于配置文件的Spring AOP的实现。实现了前置通知,后置通知,以及拦截器的功能,配置中有详细的注释。
java xml方式实现springaop编程,包含源码+jar包+解释
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想