spring学习笔记7--使用spring进行面向切面的(AOP)编程(1)注解方式实现

前言:最近在复习spring特记录于此,欢迎大家交流指正 QQ:767872620

spring提供两种切面编程的使用方式:
(1)基于注解方式进行AOP开发

(2)基于xml配置方式进行AOP开发

一、环境配置
1.在配置文件中引入aop命名空间
 xmlns:aop="http://www.springframework.org/schema/aop"
 
 xsi:schemaLocation中导入:
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
2.导入jar包
http://www.springsources.org/downl
dist\spring.jar
lib\jakarta-commons\commons-logging.jar
使用aop另外导入:
lib\aspectj\aspectjweaver.jar和aspectjrt.jar
lib\cglib\cglib-nodep-2.2.2.jar
使用JSR-250中的注解,如@Resource
commons-annotations.jar

二、基于注解方式进行AOP开发
启动对@AspectJ注解的支持
<!-- 引入注解解释器 -->
<aop:aspectj-autoproxy/>
 

例子代码如下:

依然是熟悉的Person相关业务类

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

 

package cn.itcast.service.imp;

import cn.itcast.service.PersonService;

public class PersonServiceBean implements PersonService {


	public String getPersonName() {
		System.out.println("我是getPersonName()");
		return "xxx";
	}

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


	public void save(String name) {
		throw new RuntimeException("我爱意外"); //用于测试意外通知
//		System.out.println("我是save()");		
	}


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

}


切面代理类(注解实现):

package cn.itcast.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 Mars
 *
 */
Aspect //将此类标记为拦截类(代理类)
public class MyInterceptor {
	/**
	 * 
	 * 1.拦截方法
	 * @Pointcut("execution(* cn.itcast.service..*.*(..)))")
	 * execution:执行业务方式是进行拦截
	 * *:返回值类型,*代表任何返回值类型
	 * cn.itcast.service:包名
	 * ..:对子包也进行拦截
	 * *:包下的什么类,*代表对所有类进行拦截
	 * *:指方法,*代表对所有的方法进行拦截
	 * ..:指方法的参数随意
	 */
	@Pointcut("execution(* cn.itcast.service.imp.PersonServiceBean.*(..))")
	private void anyMethod(){} //声明一个切入点
	
/*	*//**
	 * 2.前置通知
	 * 拦截方法后在执行业务方法之前进行执行
	 * 注解参数为切入点方法的名称,记得加括号
	 * 暂时不要参数
	 *//*
	@Before("anyMethod()")
	public void doAccessCheck(){
		System.out.println("你好!我是前置通知,下面请业务方法闪亮登场");
	}*/
	/**
	 * 前置通知
	 * 获取执行业务方法的用户输入参数
	 * @Before("anyMethod() && args(username)") 
	 * 拦截到的方法参数必须是一个,而且是必须是String的才会进入前置通知
	 * 其他的方法不执行前置通知方法
	 * 注解中的args(username)与public void doAccessCheck(String username)的参数必须一样
	 * 
	 */
	@Before("anyMethod() && args username)")
	public void doAccessCheck(String username){
		System.out.println("前置参数:"+username+"你好!我是前置通知,下面请业务方法闪亮登场");
	}
	
/*	*//**
	 * 2.后置通知
	 * 拦截方法后在执行业务方法之后进行执行
	 * 注解参数为切入点方法的名称,记得加括号
	 * 暂时不要参数
	 *//*
	@AfterReturning("anyMethod()")
        public void doAfterReturning(){
		System.out.println("业务方法执行完了,该我后置通知了!");
	}*/
	
	/**
	 * 后置通知
	 * 获取业务方法的返回值
	 * 说明:
	 * 注解参数returning="result"作用
	 * 1.获取业务方法返回值的类型为String类型
	 * 2.获取的返回值最为后置通知的参数传入后置方法
	 */
	@AfterReturning(pointcut="anyMethod()",returning="result")
	public void doAfterReturning(String result){
		System.out.println("业务方法执行完了,该我后置通知了!"+result);
	}
	
	/**
	 * 3.最终通知
	 * 后置通知执行完后执行最终通知
	 */
	@After("anyMethod()")
	public void doAfter(){
		System.out.println("后置通知完事了!是我最终通知");
	}
/*	*//**
	 * 4.意外通知
	 * 当执行业务方法时抛异常,执行意外通知
	 * 后置通知不会在被执行,前置通知、最终通知、意外通知都会被执行
	 *//*
	@AfterThrowing("anyMethod()")
	public void doAfterThrowing(){
		System.out.println("意外通知");
	}*/
	/**意外通知
	 * 获取业务方法抛出的意外
	 * 
	 */
	@AfterThrowing(pointcut="anyMethod()", throwing=" e")
         public void doAfterThrowing( Exception e){
		System.out.println("意外通知" + e);
	}
	/*
	 * 
	 * 5.环绕通知
	 * 必须在环绕通知内部执行pjp.proceed();
	 * 否则后面的切面和业务方法不会被执行。
	 * 执行顺序:
	 *环绕通知->后面的切面(可以没有)-->目标对象的业务方法
	 */
	@Around("anyMethod()")
	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
		//if(){//判断用户是否有权限
		System.out.println("进入环绕通知方法");
		Object result = pjp.proceed();
		System.out.println("退出环绕通知方法");
		//}
		return result;
	}
} 

配置文件:

 

<?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:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
 <aop:aspectj-autoproxy/>
 <!-- 通过xml配置bean将拦截类交由spring管理 -->
 <bean id="myInterceptor"class="cn.itcast.service.MyInterceptor"></bean>
 <bean id="PersonService"class="cn.itcast.service.imp.PersonServiceBean"></bean>
 
</beans>



测试类(有点简陋):

package junit.test;


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

import cn.itcast.service.PersonService;


public class SpringAOPTest {
 
 @BeforeClass
 public static void setUpBeforeClass() throws Exception{
  
 }
 @Test public void interceptorTest(){
  ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
  PersonService  personservice =  (PersonService)cxt.getBean("PersonService");
  personservice.save("xxx");
//  personservice.getPersonName(2);
 }
}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值