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

来源:互联网 发布:在手机上淘宝评价管理 编辑:程序博客网 时间:2024/05/17 05:13
前言:最近在复习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); }}


 

 

原创粉丝点击