1. 程式人生 > >使用Spring的註解方式實現AOP

使用Spring的註解方式實現AOP

Spring對AOP的實現提供了很好的支援。下面我們就使用Spring的註解來完成AOP做一個例子。

首先,為了使用Spring的AOP註解功能,必須匯入如下幾個包。aspectjrt.jar,aspectjweaver.jar,cglib-nodep.jar.

然後我們寫一個介面

package com.bird.service;

public interface PersonServer {

	public void save(String name);
	public void update(String name, Integer id);
	public String getPersonName(Integer id);
	
}

和一個介面實現類
package com.bird.service.impl;

import com.bird.service.PersonServer;

public class PersonServiceBean implements PersonServer{
	
	@Override
	public void save(String name) {
		
		System.out.println("我是save方法");
	//	throw new RuntimeException();
	}

	@Override
	public void update(String name, Integer id) {
		
		System.out.println("我是update()方法");
	}

	@Override
	public String getPersonName(Integer id) {
		
		System.out.println("我是getPersonName()方法");
		return "xxx";
	}

}

下面使用Spring註解方式對這個Bean進行方法攔截
package com.bird.service;

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;

/**
 * 切面
 * @author Bird
 *
 */
@Aspect
public class MyInterceptor {
	@Pointcut("execution(* com.bird.service.impl.PersonServiceBean.*(..))")
	private void anyMethod(){}//定義一個切入點
	
	@Before("anyMethod() && args(name)")
	public void doAccessCheck(String name){
		System.out.println(name);
		System.out.println("前置通知");
	}
	
	@AfterReturning("anyMethod()")
	public void doAfter(){
		System.out.println("後置通知");
	}
	
	@After("anyMethod()")
	public void after(){
		System.out.println("最終通知");
	}
	
	@AfterThrowing("anyMethod()")
	public void doAfterThrow(){
		System.out.println("例外通知");
	}
	
	@Around("anyMethod()")
	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("進入環繞通知");
		Object object = pjp.proceed();//執行該方法
		System.out.println("退出方法");
		return object;
	}
}
@Pointcut("execution(* com.bird.service.impl.PersonServiceBean.*(..))")
這句話是方法切入點,execution為執行的意思,*代表任意返回值,然後是包名,.*意思是包下面的所有子包。(..)代

表各種方法.

然後下面的註解就比較簡單了,就是在使用方法前和中,還有環繞攔截/

然後在Spring的配置檔案中繼續配置Bean,需要開啟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: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">
		
		<aop:aspectj-autoproxy/>
	<bean id="personServiceBean" class="com.bird.service.impl.PersonServiceBean"/>
    <bean id="myInterceptor" class="com.bird.service.MyInterceptor"/>
   
</beans>

然後建立一個Junit測試
package junit.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bird.service.PersonServer;

public class SpringAOPTest {
	
	@Test
	public void inteceptorTest(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beanAop.xml");
		PersonServer bean = (PersonServer)ctx.getBean("personServiceBean");
		bean.save(null);
	}
	

}

測試結果為
2012-3-12 18:08:39 org.springframework.context.support.AbstractApplicationContext prepareRefresh
資訊: Refreshing org[email protected]dd20f6: display name [org[email protected]dd20f6]; startup date [Mon Mar 12 18:08:39 CST 2012]; root of context hierarchy
2012-3-12 18:08:40 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from class path resource [beanAop.xml]
2012-3-12 18:08:40 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
資訊: Bean factory for application context [org[email protected]dd20f6]: org.s[email protected]b0bad7
2012-3-12 18:08:40 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
資訊: Pre-instantiating singletons in org.s[email protected]b0bad7: defining beans [org.springframework.aop.config.internalAutoProxyCreator,personServiceBean,myInterceptor]; root of factory hierarchy
null
前置通知
進入環繞通知
我是save方法
後置通知
退出方法
最終通知