spring4 aop annotation

package com.zrd.aop.annotation;
/**
 * 第一步:定義一個接口
 * 
 * @author ZRD
 *
 */
public interface IMyService {

	int add(int i, int j);
}

package com.zrd.aop.annotation;

import org.springframework.stereotype.Component;

/**
 * 第二步:定義接口的實現類
 * 
 * @author ZRD
 *
 */
@Component
public class MyServiceImpl implements IMyService {

	@Override
	public int add(int i, int j) {
		int result = i +j;
		System.out.println("add 正在執行... " + result);
		return result;
	}

}

package com.zrd.aop.annotation;

import java.util.Arrays;

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.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 第三步:聲明一個切面
 * 
 * 記錄日記的切面
 * 
 * @author ZRD
 *
 */
@Aspect
@Component
public class LogAspect {

	/**
	 * 切入點:表示在哪個類的哪個方法進行切入。配置有切入點表達式
	 */
	@Pointcut("execution(* com.zrd.aop.annotation.*.*(..))")
	public void pointcutExpression() {
		
	}
	
	/**
	 * 1 前置通知
	 * @param joinPoint
	 */
	@Before("pointcutExpression()")
	public void beforeMethod(JoinPoint joinPoint) {
		System.out.println("前置通知執行了");
	}
	
	/**
	 * 2 後置通知
	 */
	@After("pointcutExpression()") // 在方法執行之後執行的代碼. 無論該方法是否出現異常
	public void afterMethod(JoinPoint joinPoint) {
		System.out.println("後置通知執行了,有異常也會執行");
	}
	
	/**
	 * 3 返回通知
	 * 
	 * 在方法法正常結束受執行的代碼
	 * 返回通知是可以訪問到方法的返回值的!
	 * 
	 * @param joinPoint
	 * @param returnValue
	 * 
	 */
	@AfterReturning(value = "pointcutExpression()", returning = "returnValue")
	public void afterRunningMethod(JoinPoint joinPoint, Object returnValue) {
		System.out.println("返回通知執行,執行結果:" + returnValue);
	}
	
	/**
	 * 4 異常通知
	 * 
	 * 在目標方法出現異常時會執行的代碼.
	 * 可以訪問到異常對象; 且可以指定在出現特定異常時在執行通知代碼
	 * 
	 * @param joinPoint
	 * @param e
	 */
	@AfterThrowing(value = "pointcutExpression()", throwing = "e")
	public void afterThrowingMethod(JoinPoint joinPoint, Exception e){
		System.out.println("異常通知, 出現異常 :" + e);
	}
	
	/**
	 * 環繞通知需要攜帶 ProceedingJoinPoint 類型的參數. 
	 * 環繞通知類似於動態代理的全過程: ProceedingJoinPoint 類型的參數可以決定是否執行目標方法.
	 * 且環繞通知必須有返回值, 返回值即爲目標方法的返回值
	 */
	
	@Around("pointcutExpression()")
	public Object aroundMethod(ProceedingJoinPoint pjd){
		
		Object result = null;
		String methodName = pjd.getSignature().getName();
		
		try {
			//前置通知
			System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
			//執行目標方法
			result = pjd.proceed();
			//返回通知
			System.out.println("The method " + methodName + " ends with " + result);
		} catch (Throwable e) {
			//異常通知
			System.out.println("The method " + methodName + " occurs exception:" + e);
			throw new RuntimeException(e);
		}
		//後置通知
		System.out.println("The method " + methodName + " ends");
		
		return result;
	}
	
	
}

<!-- 第四步:spring配置文件:配置IOC自動掃描和AOP切面自己生產目標代理對象 -->

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

	<context:component-scan base-package="com.zrd.aop.*"></context:component-scan>
	
	<!-- 使用註解配置切面 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	
	<!-- 使用XML配置切面 -->
	<!-- 
	<aop:config>
		<aop:pointcut expression="" id=""/>
		<aop:aspect>
			<aop:after method=""/>
		</aop:aspect>
	</aop:config> 
	-->
	
</beans>


package com.zrd.aop.annotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * 第五步:測試
 *  
 * @author ZRD
 *
 */
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ApplicationContext ax = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		/** 使用切面時,一定要這樣寫,不然無法注入bean **/
		//IMyService service = ax.getBean(MyServiceImpl.class);
		IMyService service = (IMyService) ax.getBean("myServiceImpl");
	
		service.add(2, 8);
	}

}

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章