Spring——第三章 Spring与AOP(二)

添加多个通知:

<?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="myService" class="com.bjpowernode.aop06.SomeServiceImpl"/>
	
	<!--注册切片:advice -->
	<bean id="myAfterAdvice" class="com.bjpowernode.aop06.MyAfterReturningAdvice"/>
	<bean id="myBeforeAdvice" class="com.bjpowernode.aop06.MyMethodBeforeAdvice"/>
	
	<!--生成proxy-->
	<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="myService"/>
		<property name="interceptorNames" value="myBeforeAdvice,myAfterAdvice">
			
			<!--
			<array>
				<value>myBeforeAdvice</value>
				<value>myAfterAdvice</value>
			</array>
			-->
		</property>
	</bean>

</beans>

使用CGLIB代理

<?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="myService" class="com.bjpowernode.aop06.SomeServiceImpl"/>
	
	<!--注册切片:advice -->
	<bean id="myAfterAdvice" class="com.bjpowernode.aop06.MyAfterReturningAdvice"/>
	<bean id="myBeforeAdvice" class="com.bjpowernode.aop06.MyMethodBeforeAdvice"/>
	
	<!--生成proxy-->
	<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="myService"/>
		<property name="interceptorNames" value="myBeforeAdvice,myAfterAdvice">
			
			<!--
			<array>
				<value>myBeforeAdvice</value>
				<value>myAfterAdvice</value>
			</array>
			-->
		</property>
	</bean>

</beans>

3.4 顾问Advisor 

现在想只增强单独的目标方法,advice只能指定时间点,不能指定切入点。

想实现指定切入点,就要实现顾问advisor。

PointcutAdvisor 是顾问的一种,可以指定具体切入点,对通知进行包装,会根据不同的通知类型,在不同的时间点,将切面织入到不同的切入点。

PointcutAdvisor 接口有两个实现类:

NameMatchMethodPointcutAdvisor 名称匹配方法切入点顾问

RegexpMethodPointcutAdvisor 正则表达式方法切入点顾问

 

NameMatchMethodPointcutAdvisor 名称匹配方法切入点顾问

   只为doFirst和doSecond设置后置通知

<?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="myService" class="com.bjpowernode.aop09.SomeServiceImpl"/>
	
	<!--注册切片:advice -->
	<bean id="myAdvice" class="com.bjpowernode.aop09.MyAfterReturningAdvice"/>
	
	<!--注册顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<!-- 指定切入点 -->
		<!--<property name="mappedName" value="doFirst"/>-->
		<property name="mappedNames" value="doFirst,doSecond"/>
	</bean>
	
	<!--生成代理对象-->
	<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="myService"/>
		<property name="interceptorNames" value="myAdvisor"/>
	</bean>

</beans>

<?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="myService" class="com.bjpowernode.aop09.SomeServiceImpl"/>
	
	<!--注册切片:advice -->
	<bean id="myAdvice" class="com.bjpowernode.aop09.MyAfterReturningAdvice"/>
	
	<!--注册顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<!-- 指定切入点 -->
		<!--<property name="mappedName" value="doFirst"/>-->
		<!--<property name="mappedNames" value="doFirst,doSecond"/>-->
		<property name="mappedNames" value="*ir*"/>
	</bean>
	
	<!--生成代理对象-->
	<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="myService"/>
		<property name="interceptorNames" value="myAdvisor"/>
	</bean>

</beans>

RegexpMethodPointcutAdvisor 正则表达式方法切入点顾问

	<!--注册顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<!-- 指定切入点 -->
		<!--<property name="mappedName" value="doFirst"/>-->
		<!--<property name="mappedNames" value="doFirst,doSecond"/>-->
		<!--这里的正则表达式匹配的对象是全限定性方法名 -->
		<!--<property name="pattern" value=".*doFirst"/>-->
		<!--<property name="patterns" value=".*doFirst,.*doSecond"/>-->
		<property name="pattern" value=".*doFirst|.*doSecond"/>
	</bean>

-这里的正则表达式匹配的对象是全限定性方法名 

	<!--注册顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<!-- 指定切入点 -->
		<!--<property name="mappedName" value="doFirst"/>-->
		<!--<property name="mappedNames" value="doFirst,doSecond"/>-->
		<!--这里的正则表达式匹配的对象是  全限定性方法名 -->
		<!--<property name="pattern" value=".*doFirst"/>-->
		<!--<property name="patterns" value=".*doFirst,.*doSecond"/>-->
		<!--<property name="pattern" value=".*doFirst|.*doSecond"/>-->
		<property name="pattern" value=".*S.*"/>
	</bean>

 

3.5 自动代理生成器 

当前代码存在的两个问题:

1)一个目标对象对应一个代理对象,当目标对象太多时,就会使用多次ProxyFactoryBean来创建多个代理对象,会使xml文件太长,不便于管理。

2)用户真正想调用的是目标对象,真正可以调用的是代理对象,这不符合正常的逻辑

以上这俩问题,均为ProxyBeanFactory这个类太简单引起的。

自动代理生成器:实现了Bean后处理器接口,可以自动装载Bean,无需id。自动代理生成器的功能是在service Bean初始化前后调用before和after两种方法,这两种方法通过advisor(顾问)来实现对目标类的增强。

3.5.1 默认自动代理生成器

<?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="myService" class="com.bjpowernode.aop11.SomeServiceImpl"/>
	<bean id="myService2" class="com.bjpowernode.aop11.SomeServiceImpl"/>
	
	<!--注册切面:通知 -->
	<bean id="myAdvice" class="com.bjpowernode.aop11.MyAfterReturningAdvice"/>
	
	<!--注册顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<property name="mappedName" value="doFirst"/>
	</bean>
	
	<!--注册自动代理生成器-->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
	<!--
		DefaultAdvisorAutoProxyCreator存在三个问题:
		1)不能选择目标对象
		2)不能选择切面类型,切面只能是advisor
		3)不能选择Advisor,所以advisor均将被作为切面织入到目标方法
	-->
	

</beans>

3.5.2 Bean名称自动代理生成器    


        DefaultAdvisorAutoProxyCreator存在三个问题:
        1)不能选择目标对象
        2)不能选择切面类型,切面只能是advisor
        3)不能选择Advisor,所以advisor均将被作为切面织入到目标方法

<?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="myService" class="com.bjpowernode.aop12.SomeServiceImpl"/>
	
	<bean id="myService2" class="com.bjpowernode.aop12.SomeServiceImpl"/>
	
	<!--注册切面:通知 -->
	<bean id="myAdvice" class="com.bjpowernode.aop12.MyAfterReturningAdvice"/>
	
	<!--注册切面:顾问 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<property name="mappedName" value="doFirst"/>
	</bean>
	
	<bean id="myAdvisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="myAdvice"/>
		<property name="mappedName" value="doSecond"/>
	</bean>
	
	<!--注册自动代理生成器 -->
	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<!--指定目标对象 -->
		<property name="beanNames" value="myService"/>
		<!--指定切片 -->
		<property name="interceptorNames" value="myAdvice"/>
	</bean>

	<!--
		DefaultAdvisorAutoProxyCreator存在三个问题:
		1)不能选择目标对象
		2)不能选择切面类型,切面只能是advisor
		3)不能选择Advisor,所以advisor均将被作为切面织入到目标方法
	-->
	

</beans>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值