`
ch_space
  • 浏览: 111738 次
  • 性别: Icon_minigender_1
  • 来自: 农村进城务工人员
社区版块
存档分类
最新评论

Spring AOP(4)

阅读更多
在第三节里面,完满讲了使用@AspectJ注解实现Spring AOP,它需要运行在Java5以上的版本中,对于Java1.4之前的版本,我们也想使用Spring AOP,那么怎么办呢?
一种是像1,2节里面讲的那样,定义Advice实现MethodBeforeAdvice、MethodAfterAdvice、ThrowsAdvice、MethodInterceptor接口之一,然后包装在Advisor中,最后使用BeanPostProcessor(如BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator)创建业务Bean的代理对象。显然这种方式很繁琐。
第二种选择是使用Spring的<aop:...>命名空间,这是在2.0版本以后引入的。它可以运行在Java1.4基础上。本节主要介绍使用<aop:...>基于xml配置实现Spring AOP。
1、定义业务Bean
package spring.aop;
public class UserService {
	public void getUser(int id){
		System.out.println("the user id: "+id);
	}
}

2、定义切面
public class UserAspect {
	//业务方法执行前会执行此操作
	public void before() {
		System.out.println("before advice");
	}
	//业务方法正常执行结束后会执行此操作
	public void afterReturn() {
		System.out.println("after-returning advice");
	}
	//相当于finally,无论业务方法是否产生异常,执行后都会执行此操作
	public void after() {
		System.out.println("after advice");
	}
}

这里的切面就是一个简单的POJO,不需要实现任何接口,不需要继承任何类。里面的方法就是一个Advice(包括before、after、after-throwing、after-return、around五种类型),而Pointcut在xml配置。
3、配置xml
<bean id="userService" class="spring.aop.UserService"/>
<bean id="aspect" class="spring.aop.UserAspect"/>
<aop:config>
	<aop:pointcut id="pointcut" expression="execution(* spring.aop.UserService.* (..))"/>
	<aop:aspect ref="aspect">
		<aop:before pointcut-ref="pointcut" method="before"/>
		<aop:after-returning pointcut-ref="pointcut" method="afterReturn" >
		<aop:after pointcut-ref="pointcut" method="after">
	</aop:aspect>
</aop:config>


测试代码:
ApplicationContext con=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us=(UserService)con.getBean("userService");
us.getUser(12);

输出结果:
before advice
the user id: 12
after-returning advice
after advice

4、环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable{
	try{
		System.out.println("around advice: before");
		Object obj=pjp.proceed();//必须调用此方法,否则后续处理终断
		System.out.println("around advice: after-returning");
		return obj;
	}catch(Exception e){
		throw e;
	}
}

对应的xml配置:
<aop:aspect ref="aspect">
	<aop:around pointcut-ref="pointcut" method="around"/>
</aop:aspect>

环绕通知使我们有机会在方法执行的前后都作出相应的处理,功能最为强大,但必须包含一个处理连接点参数ProceedingJoinPoint pjp,并在与处理(before)之后调用pjp.proceed(),忘记次调用会带来莫名其妙的结果,所以能使用其他Advice进行处理的,尽量使用其他更简单的Advice。

5、异常
public void exception(Exception e) {
	//记录异常
	System.out.println("exception ["+e+"]");
}

这里参数Exception e是必须的。在xml配置中也必须指明此参数:throwing="e"
对应的xml配置:
<aop:aspect ref="aspect">
	<aop:after-throwing pointcut-ref="pointcut" method="exception" throwing="e"/>
</aop:aspect>

6、使用带参数的Advice
上面的例子中除了around和after-throwing含有参数,且around中的参数不需要xml中配置,其他的Advice都是无参数的,要想使用带有自定义参数的Advice,怎么办呢?此时就需要重新配置Pointcut了:
例子,一个带参数的before Advice:
定义业务Bean:
public class UserService {
	public void login(User user){
		System.out.println("user id: "+u.getId());
	}
}

定义before Advice:
public void before(User user) {
	System.out.println("user "+u.getName()+"try to login...");
}

在xml中配置Pointcut:
<aop:config>
	<aop:pointcut id="pointcut" expression="execution(* spring.aop.UserService.* (User)) and args(u)"/>
	<aop:aspect ref="aspect">
		<aop:before pointcut-ref="pointcut" method="before" arg-names="u"/>
	</aop:aspect>
</aop:config>

关键在于这一行:expression="execution(* spring.aop.UserService.* (User)) and args(u)",指明了切入点为spring.aop.UserService的任何方法,并且此方法含有一个类型的User的参数,参数名为u(可以与业务Bean中的参数名不一样,实际上是它的一个别名),<aop:before../>中arg-names就是引用的这个别名(可以与Advice中的参数名不一样)。

注意:
其他Advice不能共享此Pointcut,除非Advice中的参数与此Pointcut中的参数一致。



有人会问,如果Advice中只使用业务Bean方法的部分参数,该如何做呢?
答案是:依然利用Pointcut配置。
Demo:
定义业务Bean:
public class UserService {
	public void login(String name,String psw){
		System.out.println("login...");
	}
}

定义before Advice:
public void before(String n) {
	System.out.println("user "+n+" try to login...");
}

在xml中配置Pointcut:
<aop:config>
	<aop:pointcut id="pointcut" expression="execution(* spring.aop.UserService.* (String,..)) and args(n,..)"/>
	<aop:aspect ref="aspect">
		<aop:before pointcut-ref="pointcut" method="before" arg-names="n"/>
	</aop:aspect>
</aop:config>

(String,..)声明切入点至少含有一个String类型的参数,显然可以匹配UserService中的login(String name,String psw);
args(n,..)声明给login(String name,String psw)的第一个参数起了个别名“n”传递给Advice,如果<aop:before...>中arg-names不是“n”,将抛出异常。

7、Advice的顺序
1)一般情况下,before、after-throwing、after的执行顺序是一定的,即:
before-->after-throwing-->after
而before与around中的proceed()方法调用之前的处理则是按照谁配在前谁先处理的原则,after与around中的proceed()方法调用之后的处理也是如此;
当异常抛出时,after-returning操作不会被处理,而after-throwing、after依次被处理。
2)如果是基于注解的方式,在测试中发现是按照如下顺序执行增强的:
before advice
around advice: before
login...
around advice: after-returning
after-returning advice
after advice
分享到:
评论

相关推荐

    springAOP 4个jar包

    4. **aopalliance-1.0.jar**:AOP Alliance是一个接口集,为不同的AOP框架提供了一个统一的API。Spring AOP和AspectJ等框架都遵循这些接口,使得它们可以互操作。比如,`org.aopalliance.intercept....

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    Spring AOP 16道面试题及答案.docx

    Spring AOP,全称为Aspect Oriented Programming,是面向切面编程的一种编程范式,它是对传统的面向对象编程(OOP)的一种补充。在OOP中,核心是对象,而在AOP中,核心则是切面。切面是关注点的模块化,即程序中的...

    简单spring aop 例子

    4. **测试**:在测试类中,创建Spring容器并调用`UserService`的方法,你会看到日志信息先于方法执行输出。 以上就是Spring AOP的基本用法。在实际项目中,你可以根据需求定义不同的通知类型,如`@After`、`@Around...

    Spring AOP完整例子

    在本教程中,我们将深入探讨Spring AOP的不同使用方法,包括定义切点、通知类型、组装切面以及使用JUnit4进行测试。 首先,我们需要理解Spring AOP的基础概念。AOP的核心是切点(Pointcut),它定义了关注点在何处...

    spring aop依赖jar包

    现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...

    Spring Aop四个依赖的Jar包

    4. **aopalliance-1.0.jar**:AOP Alliance是一个包含AOP领域通用接口的库,旨在促进不同AOP实现之间的互操作性。Spring AOP就是基于这些接口进行设计的,因此这个库是Spring AOP和其他AOP实现之间协作的基础。 在...

    spring-aop.jar各个版本

    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-...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...

    Spring AOP面向方面编程原理:AOP概念

    4. **丰富的切入点表达式语言**:Spring AOP支持使用SpEL(Spring Expression Language)来定义复杂的切入点表达式,这让开发者能够更加灵活地控制通知的触发条件。 #### 四、Spring AOP的实现示例 接下来,我们...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...

    Spring AOP实现机制

    **Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    spring aop 五个依赖jar

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、事务管理等。在Java应用中,AOP通过代理模式实现了切面编程,使得我们可以将业务逻辑...

    spring AOP 引入jar包,spring IOC 引入Jar包

    Spring AOP 和 Spring IOC 是 Spring 框架的两个核心组件,它们对于任何基于 Java 的企业级应用开发都至关重要。Spring AOP(面向切面编程)允许开发者在不修改源代码的情况下,通过“切面”来插入新的行为或增强已...

    spring AOP依赖三个jar包

    Spring AOP,即Spring的面向切面编程模块,是Spring框架的重要组成部分,它允许开发者在不修改源代码的情况下,对程序进行横切关注点的处理,如日志、事务管理等。实现这一功能,主要依赖于三个核心的jar包:aop...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    面向切面编程(AOP)是一种编程范式,旨在将横切关注点(如日志、安全等)与业务逻辑分离,从而提高模块化。...利用Java反射机制和Spring AOP框架,开发者可以方便地实现AOP,从而提升代码的模块化和可维护性。

    spring aop的demo

    在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...

    spring-aop实例

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种强大的方式来实现横切关注点,如日志、事务管理、安全性等,从而解耦应用程序的核心业务逻辑。在Spring AOP中,关注点被模块化为独立的“切面”...

    spring aop 学习笔记

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和抽象化的方法来处理系统中的交叉关注点,如日志、事务管理、安全性等。本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际...

Global site tag (gtag.js) - Google Analytics