開源框架spring詳解-----AOP的深刻理解
AOP的理解
1、AOP的概述
AOP是一種不同于OOP(面向?qū)ο缶幊?的編程模式,它不是OOP的替代,而是對(duì)OOP的一種有益補(bǔ)充。
2、spring AOP的原理
3、spring AOP的實(shí)現(xiàn)
在spring2.5中,常用的AOP實(shí)現(xiàn)方式有兩種。第一種是基于xml配置文件方式的實(shí)現(xiàn),第二種是基于注解方式的實(shí)現(xiàn)。
接下來,以具體的是理智講解這兩種方式的使用。
Java代碼
- package com.zxf.service;
- /**
- * 業(yè)務(wù)邏輯接口
- * @author z_xiaofei168
- */
- public interface AccountService {
- public void save(String loginname, String password);
- }
- 它的實(shí)現(xiàn)類
- package com.zxf.service;
- import com.zxf.dao.AccountDao;
- /**
- * AccountService的實(shí)現(xiàn)類
- * @author z_xiaofei168
- */
- public class AccountServiceImpl implements AccountService {
- private AccountDao accountDao;
- public AccountServiceImpl() {}
- /** 帶參數(shù)的構(gòu)造方法 */
- public AccountServiceImpl(AccountDao accountDao){
- this.accountDao = accountDao;
- }
- public void save(String loginname, String password) {
- accountDao.save(loginname, password);
- throw new RuntimeException("故意拋出一個(gè)異常。。。。");
- }
- /** set方法 */
- public void setAccountDao(AccountDao accountDao) {
- this.accountDao = accountDao;
- }
- }
對(duì)于業(yè)務(wù)系統(tǒng)來說,AccountServiceImpl類就是目標(biāo)實(shí)現(xiàn)類,它的業(yè)務(wù)方法,如save()方法的前后或代碼會(huì)出現(xiàn)異常的地方都是AOP的連接點(diǎn)。
下面是日志服務(wù)類的代碼:
Java代碼
- package com.zxf.aspect;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- /**
- * 日志切面類
- * @author z_xiaofei168
- */
- public class LogAspect {
- //任何通知方法都可以將第一個(gè)參數(shù)定義為 org.aspectj.lang.JoinPoint類型
- public void before(JoinPoint call) {
- //獲取目標(biāo)對(duì)象對(duì)應(yīng)的類名
- String className = call.getTarget().getClass().getName();
- //獲取目標(biāo)對(duì)象上正在執(zhí)行的方法名
- String methodName = call.getSignature().getName();
- System.out.println("前置通知:" + className + "類的" + methodName + "方法開始了");
- }
- public void afterReturn() {
- System.out.println("后置通知:方法正常結(jié)束了");
- }
- public void after(){
- System.out.println("最終通知:不管方法有沒有正常執(zhí)行完成,一定會(huì)返回的");
- }
- public void afterThrowing() {
- System.out.println("異常拋出后通知:方法執(zhí)行時(shí)出異常了");
- }
- //用來做環(huán)繞通知的方法可以第一個(gè)參數(shù)定義為org.aspectj.lang.ProceedingJoinPoint類型
- public Object doAround(ProceedingJoinPoint call) throws Throwable {
- Object result = null;
- this.before(call);//相當(dāng)于前置通知
- try {
- result = call.proceed();
- this.afterReturn(); //相當(dāng)于后置通知
- } catch (Throwable e) {
- this.afterThrowing(); //相當(dāng)于異常拋出后通知
- throw e;
- }finally{
- this.after(); //相當(dāng)于最終通知
- }
- return result;
- }
- }
這個(gè)類屬于業(yè)務(wù)服務(wù)類,如果用AOP的術(shù)語(yǔ)來說,它就是一個(gè)切面類,它定義了許多通知。Before()、afterReturn()、after()和afterThrowing()這些方法都是通知。
#p#
<1>.基于xml配置文件的AOP實(shí)現(xiàn)
這種方式在實(shí)現(xiàn)AOP時(shí),有4個(gè)步驟。
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"
- 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 "/>
- < span>bean>
- <bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
- <aop:config>
- <aop:aspect id="logAspect" ref="logAspectBean">
- <aop:pointcut id="allMethod"
- expression="execution(* com.zxf.service.*.*(..))"/>
- <aop:before method="before" pointcut-ref="allMethod" />
- <aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
- <aop:after method="after" pointcut-ref="allMethod"/>
- <aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
- < span>aop:aspect>
- < span>aop:config>
- < span>beans>
上述配置針對(duì)切入點(diǎn)應(yīng)用了前置、后置、最終,以及拋出異常后通知。這樣在測(cè)試執(zhí)行AccountServiceImpl類的save()方法時(shí),控制臺(tái)會(huì)有如下結(jié)果輸出。 前置通知:com.zxf.service.AccountServiceImpl類的save方法開始了。 針對(duì)MySQL的AccountDao實(shí)現(xiàn)中的save()方法。 后置通知:方法正常結(jié)束了。 最終通知:不管方法有沒有正常執(zhí)行完成,一定會(huì)返回的。 <2>基于注解的AOP的實(shí)現(xiàn) 首先創(chuàng)建一個(gè)用來作為切面的類LogAnnotationAspect,同時(shí)把這個(gè)類配置在spring的配置文件中。 在spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了對(duì)AspectJ基于注解的切面的支持,從而 更進(jìn)一步地簡(jiǎn)化AOP的配置。具體的步驟有兩步。 Spring的配置文件是如下的配置: Xml代碼 這是那個(gè)切面的類LogAnnotationAspect Java代碼
備注:輸出結(jié)果和前面的一樣。 【編輯推薦】