AOP_使用spring框架进行面向切面编程

用spring实现AOP有两种方式:基于xml配置方式和基于注解方式,

基于注解方式

一、架包:cglib-nodep-2.1_3.jar  aspectjweaver.jar  aspectjrt.jar(AOP)

      其它架包:common-annotations.jar   spring.jar    commons-logging.jar

二、先在配置文件中加入如下内容

<?xml version="1.0" encoding="UTF-8"?>
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
</beans>

三、启动对 aspectj 的支持,在xml文件中加入如下内容

<aop:aspectj-autoproxy />

四、编写核心代码

    PersonService.java

package com.qh.service;

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

	public void update(String name);
}

    PersonServiceImp.java

package com.qh.serviceImp;

import com.qh.service.PersonService;

public class PersonServiceImp implements PersonService {

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

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

}

    MyInterceptor.java

package com.qh.service;
/*
 * 切面的实现
 */
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
//指明该类为一个切面
@Aspect
public class MyInterceptor {
	/*定义切入点,拦截方法
	 *使用AOP表述是语言:执行(返回值类型  要拦截的包  子包  类.方法(任意参数))
	 *该句解释:执行 com.qh.service及其子包中的所有类的所有带任意参数的方法,并返回任意类型值
	 */
	@Pointcut("execution(* com.qh.service..*.*(..))")
	private void anyMethod(){}//声明一个切入点名称anyMethod()
	@Before("anyMethod()")//定义前置通知,当然还有其它通知
	public void doprint(){
		System.out.println("执行!");
	}
} 
//其它通知      
	//只拦截包含一个参数的方法,并将该参数传给doBefore()方法
	@Before("anyMethod()&&args(str)")
	public void doBefore(String str){
		System.out.println("我是前置通知!"+str);
	}
	//定义后置通知,将拦截的方法的返回结果作为doAfterReturning()方法的参数
	@AfterReturning(pointcut="anyMethod()",returning="str")
	public void doAfterReturning(String str){
		System.out.println("我是后置通知!"+str);
	}
	//定义例外通知,将异常信息作为doAfterThrowing()方法的参数
	@AfterThrowing(pointcut="anyMethod()",throwing="e")
	public void doAfterThrowing(Exception e){
		System.out.println("我是例外通知!"+e);
	}
	@After("anyMethod()")//定义最终通知
	public void doAfter(){
		System.out.println("我是最终通知!");
	}
	@Around("anyMethod()")//定义环绕通知,此方法适合做权限控制
	//此方法格式固定
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("我是环绕通知!进入方法");
		//if(){
		Object object=pjp.proceed();//一定要执行的方法,假如不执行该方法,被拦截的方法是不会执行的
		//}
		System.out.println("我是环绕通知!退出方法");
		return object;
	}

 

五、将PersonServiceImp和MyInterceptor类交给spring容器  

<bean id="personServiceImp" class="com.qh.serviceImp.PersonServiceImp"></bean>
<bean id="myInterceptor" class="com.qh.service.MyInterceptor"></bean>

六、编写测试代码:InterceptorTest.java

package com.qh.test;

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

import com.qh.service.PersonService;

public class InterceptorTest {

	@Test
	public void test() {
		ApplicationContext apx=new ClassPathXmlApplicationContext("beans.xml");
		PersonService personService=(PersonService) apx.getBean("personServiceImp");
		personService.save("xionggui");
	}

}

 七、结果

      执行!
      我是save()方法!xionggui

 八、小结(针对本例)

     例外通知出现在Junit的控制台中、环绕通知多用于权限控制

基于xml配置方式

一、架包和第一种方式一样

二、xml文件

<aop:config><!-- aop配置 -->
<aop:aspect id="aopCut" ref="myInterceptor"><!-- 引用切面 -->
<!-- 可以定义多个切入点 -->
<aop:pointcut expression="execution(* com.qh.service..*.*(..)) and args(str)" id="myPointcut"/>
<aop:pointcut expression="execution(* com.qh.service..*.*(..))" id="myPointcut2"/>
<aop:before method="doBeforeOne" pointcut-ref="myPointcut2" />
<aop:before method="doBefore" pointcut-ref="myPointcut" arg-names="str"/>
<aop:after-returning method="doAfterReturning" pointcut-ref="myPointcut" arg-names="str"/>
<!-- aop:after-throwing method="doAfterThrowing"  pointcut-ref="myPointcut"/-->
<aop:after method="doAfter" pointcut-ref="myPointcut2"/>
<aop:around method="doAround" pointcut-ref="myPointcut2"/>
</aop:aspect>
</aop:config>

三、PersonServiceImp.java

package com.qh.service;
/*
 * 切面的实现
 */
import org.aspectj.lang.ProceedingJoinPoint;
public class MyInterceptor {
	
	public void doBeforeOne(){
		System.out.println("我是第一个前置通知!");
	}
	public void doBefore(String str){
		System.out.println("我是前置通知!"+str);
	}
	public void doAfterReturning(String str){
		System.out.println("我是后置通知!"+str);
	}
	public void doAfterThrowing(Exception e){
		System.out.println("我是例外通知!"+e);
	}
	public void doAfter(){
		System.out.println("我是最终通知!");
	}
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("我是环绕通知!进入方法");
		//if(){
			Object object=pjp.proceed();//一定要执行的方法,假如不执行该方法,被拦截的方法是不会执行的
		//}
		System.out.println("我是环绕通知!退出方法");
		return object;
	}
}

    其它代码和第一种方法一样。

四、注意

    要将上面2个类交给spring容器管理

    需要注意切入点执行的方法的参数

            

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值