`
black_angle
  • 浏览: 47913 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

实现Spring AOP 应用的几种方式

阅读更多

 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开发指南

    依赖注入的几种实现类型 Type1 接口注入 Type2 设值注入 Type3 构造子注入 几种依赖注入模式的对比总结 Spring Bean封装机制 Bean Wrapper Bean Factory ApplicationContext Web Context Spring 高级...

    java面试Spring.pdf

    1. Spring 介绍 1.1 Spring 的优点 ...说一下Spring基于xml注入bean的几种方式? Spring如何解决循环依赖问题? Spring的自动装配 Spring框架中都用到了哪些设计模式? Spring框架中有哪些不同类型的事件?

    Spring面试题含答案.pdf

    25. 解释 Spring 支持的几种 bean 的作用域 26. Spring 框架中的单例 bean 是线程安全的吗? 27. 解释 Spring 框架中 bean 的生命周期 28. 哪些是重要的 bean 生命周期方法? 你能重载它们吗? 29. 什么是 Spring ...

    Spring面试专题.md

    &emsp;Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架...* Spring MVC:提供面向Web应用的Model-View-Controller实现。 ## 1.3 Spring的好处 | 序号 | 好处 | 说明 | | ---- | ---

    开源框架 Spring Gossip

    从代理机制初探 AOP 动态代理 &lt;br&gt;AOP 观念与术语 Spring AOP Advices Advices 包括了Aspect 的真正逻辑,由于缝合至Targets的时机不同,Spring 提供了几种不同的 Advices。 Before ...

    Spring.net框架

    本部分代码仅仅提供一种功能演示,如果实际应用仍需进一步完善(建议使用一些成型的Ioc框架,例如Spring.net或Castle等)。经过改造后 的系统,组件间依赖关系如下图: 可以看出这次实现了真正的“针对接口编程”...

    Spring基础与快速入门

    Spring作为实现J2EE的一个全方位应用程序框架,为我们开发企业级应用提供了一个健壮、高效的解决方案。所谓全方位,不得不说以下几个特点: 1 非侵入式:对于写代码从来不考虑复用和移植的程序员来说,这一点根本...

    Spring in Action(第2版)中文版

    1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数...

    Spring in Action(第二版 中文高清版).part2

    1.4 应用AOP 1.4.1 AOP介绍 1.4.2 AOP使用 1.5 小结 第2章 基本Bean装配 2.1 容纳你的Bean 2.1.1 BeanFactory介绍 2.1.2 使用应用上下文 2.1.3 Bean的生命 2.2 创建Bean 2.2.1 声明一个简单的Bean ...

    Spring in Action(第二版 中文高清版).part1

    1.4 应用AOP 1.4.1 AOP介绍 1.4.2 AOP使用 1.5 小结 第2章 基本Bean装配 2.1 容纳你的Bean 2.1.1 BeanFactory介绍 2.1.2 使用应用上下文 2.1.3 Bean的生命 2.2 创建Bean 2.2.1 声明一个简单的Bean ...

    java面试题

    多线程几种实现方法,同步? 答:多线程有两种实现方法,一种是继承Thread类或者实现Runnable接口。同步就是在方法返回类型后面加上synchronized。 c#中的委托,事件是不是委托? 答:委托就是将方法作为一个参数...

    springmybatis

    下面对这几个配置文件解释下: 1.Configuration.xml 是 mybatis 用来建立 sessionFactory 用的,里面主要包含了数据库连接相关东西,还有 java 类所对应的别名,比如 ...

    ssh(structs,spring,hibernate)框架中的上传下载

    系统Web层将来切换到另一种实现技术的可能性也微乎其微,所以笔者觉得没有必要为了这个业务层完全独立于调用层的过高目标而去搞一个额外的隔离层,浪费了原材料不说,还将系统搞得过于复杂,相比于其它原则,"简单...

    Java常见面试题208道.docx

    98.spring 事务实现方式有哪些? 99.说一下 spring 的事务隔离? 100.说一下 spring mvc 运行流程? 101.spring mvc 有哪些组件? 102.@RequestMapping 的作用是什么? 103.@Autowired 的作用是什么? 十一、Spring ...

    史上最全java面试,103项重点知识,带目录

    98. spring 事务实现方式有哪些? 59 99. 说一下 spring 的事务隔离? 59 100. 说一下 spring mvc 运行流程? 60 101. spring mvc 有哪些组件? 61 102. @RequestMapping 的作用是什么? 62 103. @Autowired 的作用...

    java-ee电子商城系统课程设计.doc

    S2SH集成框架是Struts2、Spring 和Hibernate 三种技术的有机融合, 是目前应用最广泛的Java EE 架构。在S2SH集成框架中,Struts 的作用是提供MVC 模型, 将界面、业务逻辑和数据分离, 并提供一个高可扩展的架构。...

Global site tag (gtag.js) - Google Analytics