Spring入门6---AOP1

Spring的AOP实现

1.纯java实现,无需特殊的编译过程,不需要控制类加载层次

2.目前只支持方法执行连接点(通知Spring Bean的方法执行)

3.不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IoC容器之间的整合,用于帮助解决企业应用中的常见问题

4.Spring AOP不会与AspectJ竞争,从而提供综合全面的AOP解决方案

Spring所有的切面和通知器都必须放在一个<aop:config>内(可以配置包含多个<aop:config>元素),每一个<aop:config>可以包含pointcut , advisor 和 aspect元素

(它们必须按照这个顺序进行声明)


先来一个简单用例

1.  创建一个切面类

package aop.schema.advice;

public class MyAspect {

	public void before()
	{
		System.out.println("MyAspect:before");
	}
}


2.  创建一个需要进行AOP的业务类

package aop.schema.advice.biz;

public class AspectBiz {

	public void biz()
	{
		System.out.println("AspectBiz:biz");
	}
}


3.  在xml中配置切面

<?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.xsd  
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

	<bean id="myAspect" class="aop.schema.advice.MyAspect"></bean>
	
	<bean id="aspectBiz" class="aop.schema.advice.biz.AspectBiz"></bean>
	
	<aop:config>
		<aop:aspect id="myAspectAOP" ref="myAspect">
		    <!--该表达式的意思是,切入点是  aop.schema.advice.biz.AspectBiz 类中的所有方法 -->
			<aop:pointcut expression="execution(* aop.schema.advice.biz.AspectBiz.*(..))" id="myPiontcut"/>
			<!--指定前置通知, method中的名称即是 myAspect中的方法名,pointcut-ref 指向某一个切入点   --> 
 			<aop:before method="before" pointcut-ref="myPiontcut"/> 
		</aop:aspect>
	</aop:config>

 </beans>


4. 测试

package test.aop;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import annotation.BeanAnnotation;
import aop.schema.advice.biz.AspectBiz;


@RunWith(BlockJUnit4ClassRunner.class)
public class TestAopSchemaAdvice {
	private ClassPathXmlApplicationContext context;
	
	@Test
	public void testBean(){
		
		 context = new ClassPathXmlApplicationContext("spring-aop-schema-advice.xml");
		 AspectBiz ab = (AspectBiz) context.getBean("aspectBiz");
		 ab.biz();
	}
}


输出:

MyAspect:before

AspectBiz:biz


还可以指定 切入点方法执行完之后调用的通知 <aop:after-returning >

<?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.xsd  
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

	<bean id="myAspect" class="aop.schema.advice.MyAspect"></bean>
	
	<bean id="aspectBiz" class="aop.schema.advice.biz.AspectBiz"></bean>
	
	<aop:config>
		<aop:aspect id="myAspectAOP" ref="myAspect">
		    <!--该表达式的意思是,切入点是  aop.schema.advice.biz.AspectBiz 类中的所有方法 -->
			<aop:pointcut expression="execution(* aop.schema.advice.biz.AspectBiz.*(..))" id="myPiontcut"/>
			<!--指定前置通知, method中的名称即是 myAspect中的方法名,pointcut-ref 指向某一个切入点   --> 
 			<aop:before method="before" pointcut-ref="myPiontcut"/> 
 			<!--指定在 切入点方法返回之后调用的通知  ,method中的名称即是 myAspect中的方法名  -->
			<aop:after-returning method="afterReturning" pointcut-ref="myPiontcut"/> 

		</aop:aspect>
	</aop:config>

 </beans>

在切面类中加入 afterReturning方法

package aop.schema.advice;

public class MyAspect {

	public void before()
	{
		System.out.println("MyAspect:before");
	}
	
	public void afterReturning()
	{
		System.out.println("MyAspect:afterReturning");
	}
}

测试结果:

MyAspect:before

AspectBiz:biz

MyAspect:afterReturning


除了 after-returning 之外

1. 还可以指定抛出异常之后调用的通知 , 若抛出异常,则after-returning不会执行

<aop:after-throwing method="afterThrowing" pointcut-ref="myPiontcut"/>


2. 指定方法后置通知 after ,如果after定义在 after-returning之前,就会先被调用,反之,后被调用

当有异常抛出时 执行throwing ,但是由于是非正常结束,所以after-returning就是不会执行了,但是after 是不管你是否正常结束,都一定会执行。

<aop:after method="after" pointcut-ref="myPiontcut"/> 


2. 指定环绕通知 ,注意 通知方法的第一个参数必须是ProceedingJoinPoint类型

例如:

<!--环绕通知 ,  通知方法的第一个参数必须是 ProceedingJoinPoint类型 -->
			<aop:around method="around" pointcut-ref="myPiontcut"/> 

在myAspect定义 around方法

public Object around(ProceedingJoinPoint pjp)
	{
		Object obj =null;
		try {
			System.out.println("MyAspect: around 1");
			obj = pjp.proceed();
			System.out.println("MyAspect: around 2");
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}

运行结果

MyAspect:before

MyAspect: around 1

AspectBiz:biz

MyAspect: around 2

MyAspect:after

MyAspect:afterReturning





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值