`
z_xiaofei168
  • 浏览: 198046 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

开源框架spring详解-----AOP的深刻理解

阅读更多

开源框架spring详解-----AOP的深刻理解

AOP的理解

         1AOP的概述

                   AOP是一种不同于OOP(面向对象编程)的编程模式,它不是OOP的替代,而是对OOP的一种有益补充。

         2spring AOP的原理

         3spring AOP的实现

                   spring2.5中,常用的AOP实现方式有两种。第一种是基于xml配置文件方式的实现,第二种是基于注解方式的实现。

                   接下来,以具体的是理智讲解这两种方式的使用。

 

package com.zxf.service;

/**
 * 业务逻辑接口
 * @author z_xiaofei168
 */
public interface AccountService {
	public void save(String loginname, String password);
}

它的实现类

package com.zxf.service;
import com.zxf.dao.AccountDao;

/**
 * AccountService的实现类
 * @author z_xiaofei168
 */
public class AccountServiceImpl implements AccountService {
	private  AccountDao accountDao;
	
	public AccountServiceImpl() {}
	
	/** 带参数的构造方法 */
	public AccountServiceImpl(AccountDao accountDao){
		this.accountDao = accountDao;
	}
	
	public void save(String loginname, String password) {
		accountDao.save(loginname, password);
		throw new RuntimeException("故意抛出一个异常。。。。");
	}
	
	/** set方法 */
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
}

   

     对于业务系统来说,AccountServiceImpl类就是目标实现类,它的业务方法,如save()方法的前后或代码会出现异常的地方都是AOP的连接点。

 

下面是日志服务类的代码:

 

 

package com.zxf.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 日志切面类
 * @author z_xiaofei168
 */
public class LogAspect {

	//任何通知方法都可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型 
	public void before(JoinPoint call) {
		//获取目标对象对应的类名
		String className = call.getTarget().getClass().getName();
		//获取目标对象上正在执行的方法名
		String methodName = call.getSignature().getName();
		
		System.out.println("前置通知:" + className + "类的" + methodName + "方法开始了");
	}
	
	public void afterReturn() {
		System.out.println("后置通知:方法正常结束了");
	}
	
	public void after(){
		System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
	}
	
	public void afterThrowing() {
		System.out.println("异常抛出后通知:方法执行时出异常了");
	}
	
	//用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型
	public Object doAround(ProceedingJoinPoint call) throws Throwable {
		Object result = null;
		this.before(call);//相当于前置通知
		try {
			result = call.proceed();
			this.afterReturn(); //相当于后置通知
		} catch (Throwable e) {

			this.afterThrowing();  //相当于异常抛出后通知
			throw e;
		}finally{
			this.after();  //相当于最终通知
		}
		
		return result;
	}
}

 

     这个类属于业务服务类,如果用AOP的术语来说,它就是一个切面类,它定义了许多通知。Before()afterReturn()after()afterThrowing()这些方法都是通知。

 

<1>.基于xml配置文件的AOP实现

 

         这种方式在实现AOP时,有4个步骤。

 

<?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"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>

	<bean id="accountDaoImpl" class="com.zxf.dao.AccountDaoImpl"/>
	
	<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
		<property name=" accountDaoImpl " ref=" accountDaoImpl "/>
	</bean>

	<!-- 日志切面类 -->
	<bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
	
	<!-- 第1步: AOP的配置 -->
	<aop:config>
		<!-- 第2步:配置一个切面 -->
		<aop:aspect id="logAspect" ref="logAspectBean">
			<!-- 第3步:定义切入点,指定切入点表达式 -->
			<aop:pointcut id="allMethod" 
			    expression="execution(* com.zxf.service.*.*(..))"/>
			    
			<!-- 第4步:应用前置通知 -->
			<aop:before method="before" pointcut-ref="allMethod" />
			<!-- 第4步:应用后置通知 -->
			<aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
			<!-- 第4步:应用最终通知 -->
			<aop:after method="after" pointcut-ref="allMethod"/>
			<!-- 第4步:应用抛出异常后通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
			
			<!-- 第4步:应用环绕通知 -->
			<!-- 
			<aop:around method="doAround" pointcut-ref="allMethod" />
			 -->
		</aop:aspect>
	</aop:config>
</beans>

 

 

    上述配置针对切入点应用了前置、后置、最终,以及抛出异常后通知。这样在测试执行AccountServiceImpl类的save()方法时,控制台会有如下结果输出。

 

前置通知:com.zxf.service.AccountServiceImpl类的save方法开始了。

针对MySQLAccountDao实现中的save()方法。

后置通知:方法正常结束了。

最终通知:不管方法有没有正常执行完成,一定会返回的。

   <2>基于注解的AOP的实现

 

    首先创建一个用来作为切面的类LogAnnotationAspect,同时把这个类配置在spring的配置文件中。

        spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了对AspectJ基于注解的切面的支持,从而 更进一步地简化AOP的配置。具体的步骤有两步。

 

Spring的配置文件是如下的配置:

 

 

<?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"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>

	<bean id="accountDao" class="com.zxf.dao.AccountDaoImpl"/>
	<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	<!-- 把切面类交由Spring容器来管理 -->
	<bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>
	<!-- 启用spring对AspectJ注解的支持 -->
	<aop:aspectj-autoproxy/>
</beans>

 

这是那个切面的类LogAnnotationAspect

package com.zxf.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 日志切面类
 */
@Aspect  //定义切面类
public class LogAnnotationAspect {
	@SuppressWarnings("unused")
	//定义切入点
	@Pointcut("execution(* com.zxf.service.*.*(..))")
	private void allMethod(){}
	
	//针对指定的切入点表达式选择的切入点应用前置通知
	@Before("execution(* com. zxf.service.*.*(..))")
	public void before(JoinPoint call) {
		
		String className = call.getTarget().getClass().getName();
		String methodName = call.getSignature().getName();
		
		System.out.println("【注解-前置通知】:" + className + "类的" 
				+ methodName + "方法开始了");
	}
	//访问命名切入点来应用后置通知
	@AfterReturning("allMethod()")
	public void afterReturn() {
		System.out.println("【注解-后置通知】:方法正常结束了");
	}
	
	//应用最终通知
	@After("allMethod()")
	public void after(){
		System.out.println("【注解-最终通知】:不管方法有没有正常执行完成," 
				+ "一定会返回的");
	}
	
	//应用异常抛出后通知
	@AfterThrowing("allMethod()")
	public void afterThrowing() {
		System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");
	}
	
	//应用周围通知
	//@Around("allMethod()")
	public Object doAround(ProceedingJoinPoint call) throws Throwable{
		Object result = null;
		this.before(call);//相当于前置通知
		try {
			result = call.proceed();
			this.afterReturn(); //相当于后置通知
		} catch (Throwable e) {
			this.afterThrowing();  //相当于异常抛出后通知
			throw e;
		}finally{
			this.after();  //相当于最终通知
		}
		
		return result;
	}
}

 

  备注:输出结果和前面的一样。

 

 

 

8
6
分享到:
评论
4 楼 z_xiaofei168 2011-05-13  
Jclick 写道
这能算详解么?顶多也就是讲讲用法~~

呵呵,恩,你说的对,像我们做开发的,原理知道的不是很清楚。马马虎虎吧
3 楼 Jclick 2011-05-13  
这能算详解么?顶多也就是讲讲用法~~
2 楼 z_xiaofei168 2011-05-12  
你说的是AOP的实现原理吗?要是单纯的指spring底层是如何解析XML配置来进行拦截的,那你只有去看API,看看源码是怎么实现的。
1 楼 jiasky 2011-05-12  
只讲了用法,但没有说spring底层是如何解析XML配置来进行拦截的

相关推荐

    Spring5 框架 ---- AOP ---- 代码

    Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...

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

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    spring-aop-5.3.10-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...

    spring-aop-jar

    aopalliance.jar、spring-aop-4.1.6.RELEASE.jar、spring-aspects-4.1.6.RELEASE.jar

    spring-aop-3.2.5.RELEASE.jar ;spring-aop-3.2.5.jar

    spring-aop-3.2.5.RELEASE.jar

    spring-aop-5.3.12-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

    spring-aop-5.1.3.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.1.3.RELEASE.jar; 赠送原API文档:spring-aop-5.1.3.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.1.3.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.1.3.RELEASE.pom;...

    spring-aop-4.0.4.RELEASE

    spring-aop-4.0.4.RELEASE 的jar包,亲测可用。。。。

    spring-aop-5.1.0.RELEASE.jar

    spring-**core**-4.3.6.RELEASE.jar :包含spring框架基本的核心工具类,spring其他组件都要用到这个包里的类,其他组件的基本核心 spring-**beans**-4.3.6.RELEASE.jar:所有应用都要用到的jar包,它包含访问配置...

    spring-aop-5.0.4.RELEASE.jar

    spring-aop-5.0.4.RELEASE.jar。

    spring-aop-2.0.8.jar

    spring-aop-2.0.8.jar

    spring-aop-3.2.0.RELEASE.jar

    spring-aop-3.2.0.RELEASE.jar,一个Spring中AOP的jar包

    spring-aop-4.2.2.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...

    spring-aop-4.3.20.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-4.3.20.RELEASE.jar 赠送原API文档:spring-aop-4.3.20.RELEASE-javadoc.jar 赠送源代码:spring-aop-4.3.20.RELEASE-sources.jar 包含翻译后的API文档:spring-aop-4.3.20.RELEASE-...

    spring-aop-5.3.15-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

Global site tag (gtag.js) - Google Analytics