`
在水伊方
  • 浏览: 107487 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Spring 基于注解方式实现AOP

阅读更多

要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间,此外我们还需要启动对@AspectJ注解的支持:

 

<?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">

		<!-- 启动对@AspectJ注解的支持  -->  
        <aop:aspectj-autoproxy />    
</beans>  

 

PersonService接口

package org.spring.service;

public interface PersonService {
	public void save(String name);

	public void update(String name, Integer id);

	public String getPersonName(Integer id);
}

 

PersonService的实现类PersonServiceBean

package org.spring.service.impl;

import org.spring.service.PersonService;

public class PersonServiceBean implements PersonService {
	public String getPersonName(Integer id) {
		System.out.println("我是getPersonName()方法");
		return "xxx";
	}

	public void save(String name) {
		System.out.println("我是save()方法");
	}

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

}

 

切面

package org.spring.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;

@Aspect
public class MyInterceptor {
	// 拦截org.spring.service.impl.PersonServiceBean下返回值为任意类型的所有方法,参数可有可无,个数不限定
	@Pointcut("execution (* org.spring.service.impl.PersonServiceBean.*(..))")
	private void anyMethod() {
	}// 声明一个切入点,用一个方法表示

	@Before("anyMethod() && args(name)")
	public void doAccessCheck(String name) {
		System.out.println("前置通知:" + name);
	}

	// 返回值类型为字符串
	@AfterReturning(pointcut = "anyMethod()", returning = "result")
	public void doAfterReturning(String result) {
		System.out.println("后置通知:" + result);
	}

	@After("anyMethod()")
	public void doAfter() {
		System.out.println("最终通知");
	}

	@AfterThrowing(pointcut = "anyMethod()", throwing = "e")
	public void doAfterThrowing(Exception e) {
		System.out.println("例外通知:" + e);
	}

	// 环绕通知
	@Around("anyMethod()")
	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
		// if(){//判断用户是否在权限
		System.out.println("进入方法");
		Object result = pjp.proceed();
		System.out.println("退出方法");
		// }
		return result;
	}

}

 

我们还需要把PersonServiceBean与MyInterceptor交于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">

		<!-- 启动对@AspectJ注解的支持  -->  
        <aop:aspectj-autoproxy />    
        <bean id="myInterceptor" class="org.spring.service.MyInterceptor" />  
        <bean id="personServiceBean" class="org.spring.service.impl.PersonServiceBean" />
</beans>  

 

测试类

package org.spring.junit;

import org.junit.Test;
import org.spring.service.PersonService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
	@Test
	public void test() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"spring.xml");

		PersonService personService = (PersonService) ctx
				.getBean("personServiceBean");
		
		personService.save("xxx");
	}
}

 

控制台打印结果为:

前置通知:xxx
进入方法
我是save()方法
后置通知:null
最终通知
退出方法

 

由于save方法没有返回值,故后置通知中的result为null

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics