【Spring AOP】基于Schema配置切面

如何使用Spring的Schema配置切面?

废话不多说,直接通过一个Demo来看一下吧,这里我们需要将spring的aop命名空间加入到配置文件中。spring配置如下:
<?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:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:before method="preGreeting" pointcut="target(com.zheng.demo7.NaiveWaiter) and execution(* greetTo(..))"/>
		</aop:aspect>
	</aop:config>
	
	<bean id="adviceMethod" class="com.zheng.demo7.AdviceMethod"></bean>
		
	<!-- 目标bean -->
	<bean id="waiter" class="com.zheng.demo7.NaiveWaiter"></bean>
</beans>

增强类AdviceMethod:

public class AdviceMethod {
	// 增强方法
	public void preGreeting()
	{
		System.out.println("How are you!");
	}
}

场景调用如下:

public class Client {
	public static void main(String[] args) {
		String path = "com/zheng/demo7/applicationContext.xml";
		ApplicationContext ctx = new  ClassPathXmlApplicationContext(path);
		Waiter waiter = (Waiter) ctx.getBean("waiter");
		waiter.greetTo("John");
	}
}

输出了我们想要的效果:

How are you!

waiter greet to John

配置命名切点

上面的spring配置虽然完成了我们想要的效果,但是如果我们想要对该切点在一个切面中的不同增强进行重用怎么办呢?spring的aop配置可以声明切点,如下:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:pointcut id="greetToPointcut" expression="target(com.zheng.demo7.NaiveWaiter) and execution(* greetTo(..))"/>
			<aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
		</aop:aspect>
	</aop:config>

如果希望可以在不同切面进行重用怎么办?如下:

	<aop:config proxy-target-class="true">
		<aop:pointcut id="greetToPointcut" expression="target(com.zheng.demo7.NaiveWaiter) and execution(* greetTo(..))"/>
		<aop:aspect ref="adviceMethod">
			<aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
		</aop:aspect>
		<aop:aspect ref="adviceMethod1">
			<aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
		</aop:aspect>
	</aop:config>

各种增强类型的配置方法

前置增强已经说过,就不在提了,下面其他类增强配置方法如下:
后置增强
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:after-returning method="afterReturning" pointcut="target(com.zheng.demo8.NaiveWaiter)" returning="retVal"/>
		</aop:aspect>
	</aop:config>
	
	<bean id="adviceMethod" class="com.zheng.demo8.AdviceMethod"></bean>

returning标签为被增强方法的返回值,注意这个参数的名字必须跟增强的方法的入参名字保持一致。如下:

public class AdviceMethod {
	// 增强方法
	public void afterReturning(int retVal)
	{
		System.out.println("bye bye!");
		System.out.println("the returning is " + retVal);
	}
}
环绕增强
aop配置如下:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:around method="aroundMethod" 
				pointcut="execution(* greetTo(..)) and within(com.zheng.demo9.NaiveWaiter)"/>
		</aop:aspect>
	</aop:config>
增强方法如下:
public class AdviceMethod {
	// 增强方法
	public void aroundMethod(ProceedingJoinPoint pjp)
	{
		// 目标方法执行前的逻辑
		System.out.println("How are you!");
		try {
			pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		// 目标方法执行后的逻辑
		System.out.println("Bye bye!");
		
	}
}
抛出异常增强
aop配置:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:after-throwing method="afterThrowingMethod"
				pointcut="target(com.zheng.demo10.NaiveWaiter) and execution(* greetTo(..))"
				throwing="iae"/>
		</aop:aspect>
	</aop:config>

其中throwing="iae"对应增强方法的入参,异常的类型。增强方法如下:

public class AdviceMethod {
	// 增强方法
	public void afterThrowingMethod(IllegalArgumentException iae)
	{
		// 捕获异常的逻辑
	}
}
Final增强
aop配置:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:after method="afterMethod"
				pointcut="execution(* greetTo(..))"/>
		</aop:aspect>
	</aop:config>

增强方法如下:

public class AdviceMethod {
	// 增强方法
	public void afterMethod()
	{
		// Final增强的逻辑
	}
}
引介增强
引介增强比较特殊,aop配置如下:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:declare-parents types-matching="com.zheng.demo12.Waiter+" 
				default-impl="com.zheng.demo12.SmartSeller"
				implement-interface="com.zheng.demo12.Seller"/>
		</aop:aspect>
	</aop:config>

type-matching定义的是需要引介接口实现类型bean

impelment-interface定义引介增强需要实现的接口
default-impl定义需要实现的接口实现的业务逻辑
这样上层模块就可以通过以下的方式去调用。如下:
public class Client {
	public static void main(String[] args) {
		String path = "com/zheng/demo12/applicationContext.xml";
		ApplicationContext ctx = new  ClassPathXmlApplicationContext(path);
		Waiter waiter = (Waiter) ctx.getBean("waiter");
		waiter.greetTo("John");
		((Seller)waiter).sell("food");
	}
}

从而实现waiter类实现了seller接口的方法。

绑定连接点信息

aop的Schema配置中绑定连接点信息的方法如下:
第一,所有增强类型对应的方法第一个入参都可以声明为JoinPoint。(环绕增强可声明为ProceedingJoinPoint)访问连接点信息。
第二,后置增强通过(<aop:after-returning>)returing属性绑定返回值信息,抛出异常增强通过throwing属性访问连接点方法所抛出的异常。
第三,所有增强方法都可以通过绑定参数的切点函数绑定连接方法的入参。举例如下:
aop配置如下:
	<aop:config proxy-target-class="true">
		<aop:aspect ref="adviceMethod">
			<aop:before method="bindParams"
				pointcut="target(com.zheng.demo13.NaiveWaiter) and args(name,num,..)"/>
		</aop:aspect>
	</aop:config>

增强方法的方法入参名字必须和配置的一致,如下:

public class AdviceMethod {
	// 增强方法
	public void bindParams(int num, String name)
	{
		System.out.println("name : " + name);
		System.out.println("num : " + num);
	}
}

Advisor配置

advisor对应于spring中的切面概念,它包含一个切点和增强。基本配置跟aspect的切面配置类似,如下:
	<aop:config proxy-target-class="true">
		<aop:advisor advice-ref="beforAdvice"
			pointcut="target(com.zheng.demo14.NaiveWaiter) and execution(* greetTo(..))"/>
	</aop:config>
	
	<bean id="beforAdvice" class="com.zheng.demo14.AdviceMethod"></bean>

增强方法如下:

public class AdviceMethod implements MethodBeforeAdvice{
	
	public void before(Method method, Object[] args, Object obj)
			throws Throwable {
		System.out.println("clientName : " + args[0]);
	}
}

到此,关于Spring的Schema配置基本用法就讲完了,通过这一章的学习,感觉Spring自己提供的基于Schema的配置方式比之前自己定义切面,通过注解去实现Aop的方式要简单的多了,

而且在Spring的配置文件中清晰的描述出了横切关系,便于管理,不得不说我个人非常喜欢这种方式,简单实用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值