Spring学习(7)AOP之顾问

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/86625551

上一篇博客是介绍了通知,但是通知有很大的缺陷,那就是在我们把通知织入到目标方法的时候,只能将切面织入到目标类的所有方法中,不能指定目标类中具体的方法。

顾问是另一种切面,它可以完成更加复杂的功能。它可以指定具体的切入点。PointcutAdvisor是顾问的一种,可以制定具体的切入点。这个接口有两个常见的实现类:

  • NameMatchMethodPointcutAdvisor:名称匹配方法切入点顾问
  • RegexpMethodPointcutAdvisor:正则表达式匹配方法切入点顾问

下面看看这两个顾问如何·实现织入的。

一、NameMatchMethodPointcutAdvisor

他的意思是容器可以根据配置文件中指定的方法名来设置切入点。下面直接通过代码看看这个顾问怎么配置:

1、定义接口

//主目标接口
public interface ISomeService {
	//目标方法
	String doFirst();
	void doSecond();
	void doThird();
}

2、定义接口实现类

public class SomeServiceImpl implements ISomeService {

	public String doFirst() {
		System.out.println("doFirst");
		return "abcde";
	}

	public void doSecond() {
		System.out.println("doSecond");
	}

	@Override
	public void doThird() {
		System.out.println("doThird");
	}

}

3、定义通知

//后置通知:可以获取到目标方法的返回结果,但是无法改变其值
public class MyAfterReturningAdvice implements AfterReturningAdvice {
	//在目标方法执行之后
	//returnValue:目标方法的返回值
	public void afterReturning(Object returnValue, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
		System.out.println("后置通知内部获取参数值:returnValue:"+returnValue);
		
	}
}

4、配置文件applicationConetext.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"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
     
     <!-- 注册 目标对象-->
     <bean id="someService" class="com.fdd.aop09.SomeServiceImpl">
    </bean>
     
     <!-- 注册切面:通知 -->
    <bean id="myAdvice" class="com.fdd.aop09.MyAfterReturningAdvice">	
    </bean>
    
    <!-- 切面注册:顾问,用于指定目标类的切入点 -->
    <bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    	<property name="advice" ref="myAdvice"></property>
    	<!-- 指定切入点 -->
    	<property name="mappedName" value="doFirst"></property>
    	<!-- 指定多个切入点的方式 -->
    	<!-- <property name="mappedNames" value="doFirst,doThird"></property> -->
    </bean>
    
    <!-- 生成代理对象 -->
    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<!-- 制定目标对象 -->
    	<!-- 	<property name="targetName" value="someService"></property> -->
    	<property name="target" ref="someService"></property>
   		<!-- 指定顾问 -->
   	<property name="interceptorNames" value="myAdvisor"></property>
    </bean>

</beans>

从上面可以看到,我们在注册通知的时候没有指定哪一个目标对象,而是在顾问中声明,并把要增强的切入点名称指定,最后通过代理,将目标类和顾问链接起来,此时容器就会寻找目标类中的切入点,看看哪一个满足条件。

5、测试

	@Test
	public void test01(){
		String resource = "com/fdd/aop09/applicationContext.xml";
		ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
		ISomeService service =(ISomeService) ac.getBean("serviceProxy");
		
		service.doFirst();
		System.out.println("=====");
		service.doSecond();
		System.out.println("=====");
		service.doThird();
	}

看结果: 

我们可以看到在这里只对doFirst方法进行增强。

二、RegexpMethodPointcutAdvisor

RegexpMethodPointcutAdvisor也就是正则表达式方法顾问,容器可以根据正则表达式来设置切入点。但是此时与正则表达式进行匹配的是接口中的方法名,不是目标类中的方法名

这里面使用了正则表达式,在网上一查一大堆。

最后验证,代码和结果跟上面一样,不说了

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/86625551
今日推荐