上一章:[Spring+SpringMVC+Mybatis]框架學習筆記(四):Spring實現AOP
下一章:[Spring+SpringMVC+Mybatis]框架學習筆記(六):Spring_AspectJ實現AOPhtml
對第4章Spring實現AOP的缺點的思考:java
它將通知進行了包裝,根據通知的不一樣類型,在不一樣的時間點,將切面織入到指定的目標對象的某些鏈接點。正則表達式
PointCutAdvisor 顧問的一種,它是一個接口,有兩個實現類:spring
複習正則表達式:
(*) 星號:匹配前面的子表達式任意次 例如:ao* 能匹配 a ao aoo aooooo
(+) 加號:匹配前面的子表達式一次或屢次 例如:ao+ 能匹配 ao aoo aooooo
(.) 點 :匹配任意字符 除「\r\n」以外
.* 表明任意的一個字符串 .*add.* 表明包含add字符的任意字符串
app
實例:框架
利用實例4.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 註冊服務類,並描述依賴關係 --> <bean id="studentService" class="com.steven.spring.sysmgr.service.impl.StudentService"></bean> <!-- 註冊前置通知 --> <bean id="beforeAdvice" class="com.steven.spring.sysmgr.advice.MyBeforeAdvice"></bean> <!-- 註冊後置通知 --> <bean id="afterAdvice" class="com.steven.spring.sysmgr.advice.MyAfterAdvice"></bean> <!-- 註冊環繞通知 --> <bean id="aroundAdvice" class="com.steven.spring.sysmgr.advice.MyAroundAdvice"></bean> <!-- 註冊異常通知 --> <bean id="throwingAdvice" class="com.steven.spring.sysmgr.advice.MyThrowingAdvice"></bean> <!-- 註冊一個名稱匹配方法切入點顧問 --> <!-- 顧問Advisor比通知Advice多了一個指定方法的步驟 --> <bean id="beforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="beforeAdvice"/> <!-- 限定單個目標方法 --> <property name="mappedName" value="addStudent"/> <!-- 限定多個目標方法 --> <!-- 方法1 --> <!-- <property name="mappedNames" value="addStudent,updateStudent"/> --> <!-- 方法2 --> <!-- <property name="mappedNames"> <array> <value>addStudent</value> <value>updateStudent</value> </array> </property> --> <!-- 方法3 --> <!-- <property name="mappedNames" value="*Student"/> --> </bean> <!-- 註冊前置顧問代理生成器 --> <bean id="myBeforeAdvisorProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="studentService"/> <property name="interceptorNames" value="beforeAdvisor"/> </bean> <!-- 註冊一個正則表達式方法切入點顧問 --> <bean id="afterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="afterAdvice"/> <!--限定單種方法--> <property name="pattern" value=".*add.*"/> <!-- 限定多種 --> <property name="patterns" value=".*add.*,.*del.*"/> </bean> <!-- 註冊後置顧問代理生成器 --> <bean id="myAfterAdvisorProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="studentService"/> <property name="interceptorNames" value="afterAdvisor"/> </bean> </beans>
2)測試代理
package com.steven.spring.sysmgr.test; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.steven.spring.sysmgr.entity.Student; import com.steven.spring.sysmgr.service.IStudentService; /** * 測試顧問 * @author chenyang * */ public class AdvisorTest { private ApplicationContext ac = null; @Before public void init(){ ac = new ClassPathXmlApplicationContext("applicationContext.xml"); } //測試前置顧問,指定某些方法,使用名稱匹配切入點方法顧問來實現 @Test public void testBeforeAdvisor(){ IStudentService studentService = (IStudentService) ac.getBean("myBeforeAdvisorProxy"); studentService.addStudent(new Student()); studentService.updateStudent(new Student());//修改功能的前置通知不能被打印 } //測試後置顧問,指定某些方法,使用正則表達式切入點方法顧問來實現 @Test public void testAfterAdvisor(){ IStudentService studentService = (IStudentService)ac.getBean("myAfterAdvisorProxy"); studentService.addStudent(new Student()); studentService.delStudent(1); studentService.updateStudent(new Student()); } }
Spring提供了自動代理生成器來解決要定義多個代理生成器的問題,有兩種方式:code
總結:
第4-5章中各類技術的運用,無非是爲了一個目標:將咱們編寫的切面的實現(通知/顧問)織入到某些類的某些方法中。
實例:
利用實例4.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 註冊服務類,並描述依賴關係 --> <bean id="studentService" class="com.steven.spring.sysmgr.service.impl.StudentService"></bean> <!-- 註冊前置通知 --> <bean id="beforeAdvice" class="com.steven.spring.sysmgr.advice.MyBeforeAdvice"></bean> <!-- 註冊後置通知 --> <bean id="afterAdvice" class="com.steven.spring.sysmgr.advice.MyAfterAdvice"></bean> <!-- 註冊環繞通知 --> <bean id="aroundAdvice" class="com.steven.spring.sysmgr.advice.MyAroundAdvice"></bean> <!-- 註冊異常通知 --> <bean id="throwingAdvice" class="com.steven.spring.sysmgr.advice.MyThrowingAdvice"></bean> <!-- 註冊一個名稱匹配方法切入點顧問 --> <!-- 顧問Advisor比通知Advice多了一個指定方法的步驟 --> <bean id="beforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="beforeAdvice"/> <property name="mappedName" value="addStudent"/> </bean> <!-- 註冊一個正則表達式方法切入點顧問 --> <bean id="afterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="afterAdvice"/> <property name="pattern" value=".*add.*"/> </bean> <!-- 默認Advisor自動代理生成器,目標對象爲配置文件中註冊的全部的目標對象,advisor爲配置文件中全部的advisor --> <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean> --> <!-- bean名稱自動代理生成器,不只能夠指定目標對象,還能夠指定advise/advisor(注意:這裏均可以!) --> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="studentService"/> <property name="interceptorNames" value="beforeAdvisor"/> </bean> </beans>
2)測試默認Advisor自動代理生成器
package com.steven.spring.sysmgr.test; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.steven.spring.sysmgr.entity.Student; import com.steven.spring.sysmgr.service.IStudentService; public class DefaultAdvisorAutoProxyCreator { private ApplicationContext ac = null; @Before public void init(){ ac = new ClassPathXmlApplicationContext("applicationContextForAutoProxy.xml"); } //測試默認顧問自動代理生成器 @Test public void testDefaultAdvisorAutoProxyCreator(){ // 注意:這裏是直接取容器中定義的目標對象的id,再也不使用代理生成器的id IStudentService studentService = (IStudentService) ac.getBean("studentService"); studentService.addStudent(new Student()); studentService.updateStudent(new Student());//修改功能的前置通知不能被打印 } }
3)測試bean名稱自動代理生成器
package com.steven.spring.sysmgr.test; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.steven.spring.sysmgr.entity.Student; import com.steven.spring.sysmgr.service.IStudentService; public class BeanNameAutoProxyCreator { private ApplicationContext ac = null; @Before public void init(){ ac = new ClassPathXmlApplicationContext("applicationContextForAutoProxy.xml"); } //測試bean名稱自動代理生成器 @Test public void testBeanNameAutoProxyCreator(){ IStudentService studentService = (IStudentService) ac.getBean("studentService"); studentService.addStudent(new Student()); studentService.updateStudent(new Student()); } }
上一章:[Spring+SpringMVC+Mybatis]框架學習筆記(四):Spring實現AOP
下一章:[Spring+SpringMVC+Mybatis]框架學習筆記(六):Spring_AspectJ實現AOP