亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Spring AOP使用整理:各種通知類型的介紹

系統 1843 0

轉載自: http://chenjumin.iteye.com/blog/364948

?

一、基礎接口和類

???? 1、Person接口的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? interface ?Person?{??
  2. ???? public ? void ?info();??
  3. ???? public ? void ?show(String?message);??
  4. }??
      public interface Person {
	public void info();
	public void show(String message);
}
    

?

???? 2、PersonImpl類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonImpl? implements ?Person?{??
  2. ???? private ?String?name;??
  3. ???? private ? int ?age;??
  4. ??????
  5. ???? public ? void ?setName(String?name)?{??
  6. ???????? this .name?=?name;??
  7. ????}??
  8. ??
  9. ???? public ? void ?setAge( int ?age)?{??
  10. ???????? this .age?=?age;??
  11. ????}??
  12. ??
  13. ???? public ? void ?info()?{??
  14. ????????System.out.println( "\t我叫" ?+?name?+? ",今年" ?+?age?+? "歲。" );??
  15. ????}??
  16. ??
  17. ???? public ? void ?show(String?message)?{??
  18. ????????System.out.println(message);??
  19. ????}??
  20. }??
      public class PersonImpl implements Person {
	private String name;
	private int age;
	
	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void info() {
		System.out.println("\t我叫" + name + ",今年" + age + "歲。");
	}

	public void show(String message) {
		System.out.println(message);
	}
}

    

?

??? 3、bean的配置

Xml代碼 復制代碼 ? 收藏代碼
  1. <!--?目標對象?--> ??
  2. < bean ? id = "personTarget" ? class = "com.cjm.aop.PersonImpl" > ??
  3. ???? < property ? name = "name" ? value = "Raymond.chen" /> ??
  4. ???? < property ? name = "age" ? value = "30" /> ??
  5. </ bean > ??
      <!-- 目標對象 -->
<bean id="personTarget" class="com.cjm.aop.PersonImpl">
	<property name="name" value="Raymond.chen"/>
	<property name="age" value="30"/>
</bean>

    

?

二、Spring AOP支持的通知類型

???? 一)環繞通知(Around advice)

????????? 實現環繞通知需要實現org.aopalliance.intercept.MethodInterceptor接口。

?????????????? 1、PersonAroundAdvice類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonAroundAdvice? implements ?MethodInterceptor?{??
  2. ???? public ?Object?invoke(MethodInvocation?invocation)? throws ?Throwable?{??
  3. ????????System.out.println( "AroundAdvice:方法調用前" );??
  4. ??????????
  5. ???????? //不要忘記調用invocation的proceed方法哦 ??
  6. ????????Object?result?=?invocation.proceed();???
  7. ??????????
  8. ????????System.out.println( "AroundAdvice:方法調用后" );??
  9. ???????? return ?result;??
  10. ????}??
  11. }??
      public class PersonAroundAdvice implements MethodInterceptor {
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("AroundAdvice:方法調用前");
		
		//不要忘記調用invocation的proceed方法哦
		Object result = invocation.proceed(); 
		
		System.out.println("AroundAdvice:方法調用后");
		return result;
	}
}

    

?

?????????????? 2、bean配置

Xml代碼 復制代碼 ? 收藏代碼
  1. < bean ? id = "personAroundAdvice" ? class = "com.cjm.aop.PersonAroundAdvice" /> ??
  2. ??
  3. <!--?代理工廠bean?--> ??
  4. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  5. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  6. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  7. ???? < property ? name = "interceptorNames" > ??
  8. ???????? < list > ??
  9. ???????????? < value > personAroundAdvice </ value > ??
  10. ???????? </ list > ??
  11. ???? </ property > ??
  12. </ bean > ??
      <bean id="personAroundAdvice" class="com.cjm.aop.PersonAroundAdvice"/>

<!-- 代理工廠bean -->
<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personAroundAdvice</value>
		</list>
	</property>
</bean>

    

?

?????????????? 3、測試代碼

Java代碼 復制代碼 ? 收藏代碼
  1. ApplicationContext?context?=? new ?FileSystemXmlApplicationContext( "classpath:com/cjm/aop/beans.xml" );??
  2. Person?p?=?(Person)context.getBean( "person" );?? //注意這里是代理工廠Bean的ID ??
  3. p.info();??
      ApplicationContext context = new FileSystemXmlApplicationContext("classpath:com/cjm/aop/beans.xml");
Person p = (Person)context.getBean("person");  //注意這里是代理工廠Bean的ID
p.info();

    

?

???? 二)前置通知(Before advice)

????????? 實現前置通知需要實現org.springframework.aop.MethodBeforeAdvice接口。

?????????????? 1、PersonBeforeAdvice類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonBeforeAdvice? implements ?MethodBeforeAdvice?{??
  2. ???? public ? void ?before(Method?method,?Object[]?args,?Object?target)? throws ?Throwable?{??
  3. ????????System.out.println( "BeforeAdvice:方法調用前" );??
  4. ????}??
  5. }??
      public class PersonBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("BeforeAdvice:方法調用前");
	}
}

    

?

?????????????? 2、bean配置

Xml代碼 復制代碼 ? 收藏代碼
  1. < bean ? id = "personBeforeAdvice" ? class = "com.cjm.aop.PersonBeforeAdvice" /> ??
  2. ??
  3. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  4. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  5. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  6. ???? < property ? name = "interceptorNames" > ??
  7. ???????? < list > ??
  8. ???????????? < value > personBeforeAdvice </ value > ??
  9. ???????? </ list > ??
  10. ???? </ property > ??
  11. </ bean > ??
      <bean id="personBeforeAdvice" class="com.cjm.aop.PersonBeforeAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personBeforeAdvice</value>
		</list>
	</property>
</bean>

    

?

???? 三)返回后通知(After Returning advice)

????????? 實現返回后通知需要實現org.springframework.aop.AfterReturningAdvice接口。

?????????????? 1、PersonAfterReturningAdvice類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonAfterReturningAdvice? implements ?AfterReturningAdvice?{??
  2. ???? public ? void ?afterReturning(Object?returnValue,?Method?method,?Object[]?args,?Object?target)? throws ?Throwable?{??
  3. ????????System.out.println( "AfterReturningAdvice:方法調用后" );??
  4. ????}??
  5. }??
      public class PersonAfterReturningAdvice implements AfterReturningAdvice {
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		System.out.println("AfterReturningAdvice:方法調用后");
	}
}

    

?

?????????????? 2、bean配置

Xml代碼 復制代碼 ? 收藏代碼
  1. < bean ? id = "personAfterReturningAdvice" ? class = "com.cjm.aop.PersonAfterReturningAdvice" /> ??
  2. ??
  3. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  4. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  5. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  6. ???? < property ? name = "interceptorNames" > ??
  7. ???????? < list > ??
  8. ???????????? < value > personAfterReturningAdvice </ value > ??
  9. ???????? </ list > ??
  10. ???? </ property > ??
  11. </ bean > ??
      <bean id="personAfterReturningAdvice" class="com.cjm.aop.PersonAfterReturningAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personAfterReturningAdvice</value>
		</list>
	</property>
</bean>

    

?

?????????????? 3、以上的配置中,通知對目標對象的所有方法都會起作用。如果需要過濾掉一部分方法,可以用正則表達式切入點配置器或者方法名匹配切入點配置器實現。

Xml代碼 復制代碼 ? 收藏代碼
  1. <!--?通知與正則表達式切入點一起配置?--> ??
  2. <!--?Advisor等于切入點加通知?--> ??
  3. <!--?方法名匹配切入點配置器:org.springframework.aop.support.NameMatchMethodPointcutAdvisor?--> ??
  4. < bean ? id = "personPointcutAdvisor" ? class = "org.springframework.aop.support.RegexpMethodPointcutAdvisor" > ??
  5. ???? < property ? name = "advice" ? ref = "personAfterReturningAdvice" /> ??
  6. ???? < property ? name = "patterns" > ??
  7. ???????? < list > ??
  8. ???????????? < value > .*info.* </ value > ??
  9. ???????? </ list > ??
  10. ???? </ property > ??
  11. </ bean > ??
  12. ??
  13. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  14. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  15. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  16. ???? < property ? name = "interceptorNames" > ??
  17. ???????? < list > ??
  18. ???????????? < value > personPointcutAdvisor </ value > ??
  19. ???????? </ list > ??
  20. ???? </ property > ??
  21. </ bean > ??
      <!-- 通知與正則表達式切入點一起配置 -->
<!-- Advisor等于切入點加通知 -->
<!-- 方法名匹配切入點配置器:org.springframework.aop.support.NameMatchMethodPointcutAdvisor -->
<bean id="personPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
	<property name="advice" ref="personAfterReturningAdvice"/>
	<property name="patterns">
		<list>
			<value>.*info.*</value>
		</list>
	</property>
</bean>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personPointcutAdvisor</value>
		</list>
	</property>
</bean>

    

?

???? 四)異常通知(Throws advice)

????????? 當連接點拋出異常時,異常通知被調用。實現異常通知需要實現org.springframework.aop.ThrowsAdvice接口,該接口不包含任何方法,但在實現該接口時必須實現如下形式的方法:
???????????????? afterThrowing([Method], [args], [target], Throwable subclass)
????????? 可以實現一個或多個這樣的方法。在這些方法中,只有第四個參數是必需的,前三個參數可選。

?

????????? 1、PersonThrowsAdvice類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonThrowsAdvice? implements ?ThrowsAdvice?{??
  2. ???? public ? void ?afterThrowing(FileNotFoundException?ex){??
  3. ????????System.out.println( "ThrowsAdvice?>>?FileNotFoundException:" ?+?ex.toString());??
  4. ????}??
  5. ??
  6. ???? public ? void ?afterThrowing(Object[]?args,?Exception?ex){??
  7. ????????System.out.println( "ThrowsAdvice?>>?Exception:" ?+?ex.getMessage());??
  8. ????}??
  9. ??
  10. ???? public ? void ?afterThrowing(Method?method,?Object[]?args,?Object?target,?Throwable?ex){??
  11. ????????System.out.println( "ThrowsAdvice?>>?Throwable:" ?+?ex.getMessage());??
  12. ????}??
  13. }??
      public class PersonThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(FileNotFoundException ex){
		System.out.println("ThrowsAdvice >> FileNotFoundException:" + ex.toString());
	}

	public void afterThrowing(Object[] args, Exception ex){
		System.out.println("ThrowsAdvice >> Exception:" + ex.getMessage());
	}

	public void afterThrowing(Method method, Object[] args, Object target, Throwable ex){
		System.out.println("ThrowsAdvice >> Throwable:" + ex.getMessage());
	}
}

    

?

??????????2、bean配置

Xml代碼 復制代碼 ? 收藏代碼
  1. < bean ? id = "personThrowsAdvice" ? class = "com.cjm.aop.PersonThrowsAdvice" /> ??
  2. ??
  3. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  4. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  5. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  6. ???? < property ? name = "interceptorNames" > ??
  7. ???????? < list > ??
  8. ???????????? < value > personThrowsAdvice </ value > ??
  9. ???????? </ list > ??
  10. ???? </ property > ??
  11. </ bean > ??
      <bean id="personThrowsAdvice" class="com.cjm.aop.PersonThrowsAdvice"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personThrowsAdvice</value>
		</list>
	</property>
</bean>

    

?

???? 五)引入通知(Introduction advice)

?????????? 引入通知是一種特殊的通知,它能將新的成員變量、成員方法引入到目標類中。它不能作用于任何切入點,因為它只作用于類層次,而不是方法層次。實現引入通知需要實現IntroductionAdvisor和IntroductionInterceptor接口。

?????????? 引入通知不能調用proceed方法。Advisor必須針對每個實例,并且是有狀態的。

?????????? 引入通知的效果類似于設計模式中的訪問者模式(Visitor Pattern)。

?

Spring AOP使用整理:各種通知類型的介紹

?

???????????1、Lockable接口的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? interface ?Lockable?{??
  2. ???? void ?lock();??
  3. ???? void ?unlock();??
  4. ???? boolean ?locked();??
  5. }??
      public interface Lockable {
	void lock();
	void unlock();
	boolean locked();
}

    

?

?????????? 2、LockableImpl類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?LockableImpl? extends ?DelegatingIntroductionInterceptor? implements ?Lockable?{??
  2. ???? private ? boolean ?locked;??
  3. ??????
  4. ???? public ? void ?lock()?{??
  5. ???????? this .locked?=? true ;??
  6. ????}??
  7. ??
  8. ???? public ? void ?unlock()?{??
  9. ???????? this .locked?=? false ;??
  10. ????}??
  11. ??
  12. ???? public ? boolean ?locked()?{??
  13. ???????? return ? this .locked;??
  14. ????}??
  15. ??
  16. ???? @Override ??
  17. ???? public ?Object?invoke(MethodInvocation?invocation)? throws ?Throwable?{??
  18. ???????? if ( this .locked){??
  19. ???????????? throw ? new ?RuntimeException( "加鎖,無法執行" );??
  20. ????????}??
  21. ??????????
  22. ???????? //這里不能調用invocation的proceed方法 ??
  23. ???????? //通常不需要改寫invoke方法,直接調用父類的該方法即可 ??
  24. ???????? return ? super .invoke(invocation);??
  25. ????}??
  26. }??
      public class LockableImpl extends DelegatingIntroductionInterceptor implements Lockable {
	private boolean locked;
	
	public void lock() {
		this.locked = true;
	}

	public void unlock() {
		this.locked = false;
	}

	public boolean locked() {
		return this.locked;
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		if(this.locked){
			throw new RuntimeException("加鎖,無法執行");
		}
		
		//這里不能調用invocation的proceed方法
		//通常不需要改寫invoke方法,直接調用父類的該方法即可
		return super.invoke(invocation);
	}
}

    

?

?????????? 3、PersonIntroductionAdvice類的源碼

Java代碼 復制代碼 ? 收藏代碼
  1. public ? class ?PersonIntroductionAdvice? extends ?DefaultIntroductionAdvisor?{??
  2. ???? public ?PersonIntroductionAdvice(){??
  3. ???????? super ( new ?LockableImpl(),?Lockable. class );??
  4. ????}??
  5. }??
      public class PersonIntroductionAdvice extends DefaultIntroductionAdvisor {
	public PersonIntroductionAdvice(){
		super(new LockableImpl(), Lockable.class);
	}
}

    

?

?????????? 4、bean配置

Xml代碼 復制代碼 ? 收藏代碼
  1. <!--?Advice必須針對每個實例,所以scope要設為prototype?--> ??
  2. < bean ? id = "personIntroductionAdvice" ? class = "com.cjm.aop.introduction.PersonIntroductionAdvice" ? scope = "prototype" /> ??
  3. ??
  4. < bean ? id = "person" ? class = "org.springframework.aop.framework.ProxyFactoryBean" > ??
  5. ???? < property ? name = "proxyInterfaces" ? value = "com.cjm.aop.Person" /> ??
  6. ???? < property ? name = "target" ? ref = "personTarget" /> ??
  7. ???? < property ? name = "interceptorNames" > ??
  8. ???????? < list > ??
  9. ???????????? < value > personIntroductionAdvice </ value > ??
  10. ???????? </ list > ??
  11. ???? </ property > ??
  12. </ bean > ??
      <!-- Advice必須針對每個實例,所以scope要設為prototype -->
<bean id="personIntroductionAdvice" class="com.cjm.aop.introduction.PersonIntroductionAdvice" scope="prototype"/>

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="proxyInterfaces" value="com.cjm.aop.Person"/>
	<property name="target" ref="personTarget"/>
	<property name="interceptorNames">
		<list>
			<value>personIntroductionAdvice</value>
		</list>
	</property>
</bean>

    

?

?????????? 5、測試代碼

Java代碼 復制代碼 ? 收藏代碼
  1. ApplicationContext?context?=? new ?FileSystemXmlApplicationContext( "classpath:com/cjm/aop/beans.xml" );??
  2. ??
  3. //獲得目標bean的代理bean ??
  4. Person?p?=?(Person)context.getBean( "person" );??
  5. ??
  6. //執行代理bean的方法,此時并未調用lock方法,可以執行 ??
  7. p.info();??
  8. ??
  9. Lockable?lockable?=?(Lockable)p;??
  10. lockable.lock();??
  11. ??
  12. //目標bean已被鎖定,此處將拋出異常 ??
  13. p.info();??

Spring AOP使用整理:各種通知類型的介紹


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 奇米在线免费视频 | 天天操天天射天天插 | 久久草在线视频播放 | 奇米一区 | 奇米777四色影视在线看 | 男女69式互添在线观看 | 久久久国产精品免费看 | 久久国产精品免费视频 | 国产理论精品 | 久久精品国产一区二区三区日韩 | 日本三级中文字幕 | 久久99热久久国产精品 | 欧美手机手机在线视频一区 | 天天干天天插天天操 | 欧美日韩国产亚洲一区二区 | 国产精品白丝喷水在线观看 | 国产精品视_精品国产免费 国产精品视频2021 | 婷婷激情五月 | 精品国产一区二区三区四区色 | 91福利视频免费观看 | 亚洲 国产 路线1路线2路线 | 一本久道久综合久久鬼色 | 一级毛片秋霞特色大片 | 久久成人免费观看全部免费 | 久久精品国产无限资源 | 日日做夜夜做 | xxx毛片| 久久久一区二区三区 | 久久国内精品视频 | 久久国产精品2020盗摄 | 国产成人综合精品 | 四虎地址| 国产精品你懂的在线播放 | 国产在线精品一区二区高清不卡 | 欧洲视频一区 | 五月激情综合婷婷 | 亚洲在线观看视频 | 国产精品18久久久久网站 | 久久综合狠狠综合久久 | 久久精品国产一区二区小说 | 亚洲国产男人本色在线观看的a站 |