【Spring】基于实现接口、基于注解、基于Schema形式的AOP五种通知的实现

一、通知(一般以前置通知为例)

&&一个普通的类    ->    有特定功能的类  
    a.继承类  b.实现接口  c.注解  d.配置

1.基于实现接口的AOP实现

a.现将需要配置通知的方法所在的类纳入IOC容器;

<!-- 配置addStudent方法所在的类 -->
	<bean id="studentService" class="com.feng.service.impl.StudentServiceImpl">
		<property name="studentDao" ref="studentDao"></property>
	</bean>
	<!-- 配置前置通知 -->
	<bean id="logBefore" class="com.feng.aop.LogBefore"></bean>

b.通过实现接口或者继承类将普通类变为通知类;

public class LogBefore implements MethodBeforeAdvice{
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("前置通知...");
	}
}

c.配置applicationContext.xml文件

<!-- 将add方法和前置通知想连接-->
<aop:config>
<!--设置切入点(起点)-->
	    <aop:pointcut expression="execution(public void com.feng.service.impl.StudentServiceImpl.addStudent(com.feng.entity.Student))" id="pointcut"/>
<!--设置连接点(终点)pointcut-ref是线->
		<aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/>
</aop:config> 

各种通知的接口:

 

2.基于注解的AOP实现

a.现将需要配置通知的方法所在的类纳入IOC容器;

b.开启注解对AOP的支持,不需要对应包的扫描器;

<!-- 使用注解实现AOP -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

c.不再需要连线了因为如下已经把方法和通知连起来了:

@Component("logAnnotation")
@Aspect
public class LogAspectAnnotation {
	@Before("execution(public * addStudent(..))")//直接定义切入点
	public void myBefore() { //紧跟这就是通知,相当于连起来了
		System.out.println("《注解形式-前置通知》");
	}
}

d.通过注解形式实现的AOP,如果想获取目标对象的参数,需要使用对象:JoinPoint,获取返回值为returning;

//后置通知
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) 
public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
System.out.println("《注解形式-后置通知》:目标对象:"
+jp.getTarget()+",方法名:"+jp.getSignature().getName()
+",参数列表:"+  jp.getArgs().length+",返回值:"+returningValue );
	}

各种通知的注解:

通知类型注解
前置通知@Before
后置通知@AfterReturning
异常通知@AfterThrowing
环绕通知@Around
最终通知@After


 

3.基于配置Schema的AOP实现

a.创建一个普通类作为通知类,并纳入IOC容器;

public class LogSchema {
	
	//后置通知方法  :JoinPoint适用于注解
	public void afterReturning(JoinPoint jp,Object returnValue) throws Throwable {
		System.out.println("后置通知:目标对象:"+jp.getThis()+",调用的方法名:"+jp.getSignature().getName()+",方法的参数个数:"+jp.getArgs().length+",方法的返回值:"+returnValue);
	}
	
	public void before() {
		System.out.println("前置通知...");
	}
	
	public void whenException(JoinPoint jp,NullPointerException e) {
		System.out.println(">>>>>>>>>>>>>>>>异常:" +e.getMessage());
	}
	//注意:环绕通知 会返回目标方法的返回值,因此返回值为Object
	public Object around(ProceedingJoinPoint jp)    {
		System.out.println("环绕通知:前置通知");
		Object result = null ; 
		try {
			 result = jp.proceed() ;//执行方法
			 System.out.println(""+jp.getSignature().getName()+","+result);
			System.out.println("环绕通知:后置通知");
		}catch(Throwable e) {
			System.out.println("环绕通知:异常通知");
		}
		return result ;
	}

}
<!-- 将准备转为 通知的类 纳入ioc容器 -->
<bean id="logSchema" class="org.lanqiao.aop.LogSchema"></bean>

b.配置applicationContext.xml文件:

<aop:config>
		<!-- 切入点(连接线的一端:业务类的具体方法) -->
		<aop:pointcut expression="execution
(public * com.feng.service.impl.StudentServiceImpl.addStudent(..))"   id="pcSchema"/>
		
		 <!-- schema方式 -->
		 <aop:aspect ref="logSchema">
		  	<!-- 连接线:连接 业务 addStudent和前置通知before -->
		 	<aop:before method="before" pointcut-ref="pcSchema"/>
		 	<!-- 连接线:连接 业务 addStudent和后置通知afterReturning -->
		 	<aop:after-returning method="afterReturning" returning="returnValue" 
pointcut-ref="pcShema"/>
		 	
		 	<aop:after-throwing method="whenException" pointcut-ref="pcSchema" throwing="e"/>
         </aop:aspect>
</aop:config>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值