Spring AOP應用實例demo



AOPAspect-Oriented Programming。面向方面編程)。能夠說是OOPObject-OrientedPrograming。面向對象編程)的補充和完好。OOP引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行為的一個集合。


OOP的問題,AOP的補充


當我們須要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP同意你定義從上到下的關系,但並不適合定義從左到右的關系。

比如日志功能。日志代碼往往水平地散布在全部對象層次中,而與它所散布到的對象的核心功能毫無關系。對於其它類型的代碼,如安全性、異常處理和透明的持續性也是如此。這樣的散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼。在OOP設計中,它導致了大量代碼的反復,而不利於各個模塊的重用。

 

所謂“方面”,簡單地說,就是將那些與業務無關。卻為業務模塊所共同調用的邏輯或責任封裝起來。便於降低系統的反復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。

 

Spring中對 AOP的支持

 

Spring AOP代理由Spring IoC容器負責生成、管理,其依賴關系也由 IoC容器負責管理。因此,AOP代理能夠直接使用容器中的其它 Bean實例作為目標,這樣的關系可由 IoC容器的依賴注入提供。Spring默認使用 Java動態代理來創建AOP代理。這樣就能夠為不論什么接口實例創建代理了。當須要代理的類不是代理接口的時候, Spring自己主動會切換為使用 CGLIB代理,也可強制使用 CGLIB


程序猿參與部分 


AOP編程事實上是非常easy的事情。

縱觀 AOP編程,當中須要程序猿參與的僅僅有三個部分:

 

   定義普通業務組件。

   定義切入點,一個切入點可能橫切多個業務組件。

   定義增強處理,增強處理就是在AOP框架為普通業務組件織入的處理動作。

 

所以進行 AOP編程的關鍵就是定義切入點和定義增強處理。一旦定義了合適的切入點和增強處理,AOP框架將會自己主動生成AOP代理。即:代理對象的方法 =增強處理 +被代理對象的方法。

 

Spring中使用方式:

 

基於 Annotation的“零配置”方式。

 

1)啟動注解。配置文件applicationContext.xml

<!-- 啟動對@AspectJ注解的支持 -->     
<aop:aspectj-autoproxy/>

<bean id="user" class="com.tgb.spring.aop.IUserImpl"/>

<bean id="check" class="com.tgb.spring.aop.CheckUser"/>

2)編寫切面類

package com.tgb.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect 
public class CheckUser {

	@Pointcut("execution(* com.tgb.spring.aop.*.find*(..))")
	public void checkUser(){
		System.out.println("**************The System is Searching Information For You****************");
	}
	
	@Pointcut("execution(* com.tgb.spring.aop.*.add*(..))")
	public void checkAdd(){
		System.out.println("**************<< Add User >> Checking.....***************");
	}
	
	@Before("checkUser()")
	public void beforeCheck(){
		System.out.println(">>>>>>>> 准備搜查用戶..........");
	}
	
	@After("checkUser()")
	public void afterCheck(){
		System.out.println(">>>>>>>> 搜查用戶完成..........");
	}

	@Before("checkAdd()")
	public void beforeAdd(){
		System.out.println(">>>>>>>> 添加用戶--檢查ing..........");
	}
	
	@After("checkAdd()")
	public void afterAdd(){
		System.out.println(">>>>>>>> 添加用戶--檢查完成!

未發現異常!.........."); } //聲明圍繞通知 @Around("checkUser()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("進入方法---圍繞通知"); Object o = pjp.proceed(); System.out.println("退出方法---圍繞通知"); return o; } }

3)定義接口

package com.tgb.spring.aop;

public interface IUser {

	public String findUser(String username);
	public void addUser(String username);
	public void findAll();
}

4)定義實現

package com.tgb.spring.aop;

import java.util.HashMap;
import java.util.Map;

public class IUserImpl implements IUser {

	public static Map map = null;
	public static void init(){
		String[] list = {"Lucy", "Tom", "小明", "Smith", "Hello"};
		Map tmp = new HashMap();
		for(int i=0; i<list.length; i++){
			tmp.put(list[i], list[i]+"00");
		}
		map = tmp;
	}
	public void addUser(String username) {
		init();
		map.put(username, username+"11");
		System.out.println("--------------【addUser】: "+username+" --------------");
		System.out.println("【The new List:"+map+"】");
	}

	public void findAll() {
		init();
		System.out.println("---------------【findAll】: "+map+" ------------------");
	}

	public String findUser(String username) {
		init();
		String password = "沒查到該用戶";
		if(map.containsKey(username)){
			password = map.get(username).toString();
		}
		System.out.println("-----------------【findUser】-----------------");
		System.out.println("-----------------Username:"+username+"-----------------");
		System.out.println("-----------------【Result】:"+password+"------------------");
		return password;
		
	}

}

5)測試

public class Test {
	
	public static void main(String as[]){
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUser user = (IUser) factory.getBean("user");
		user.findAll();
		
		User u = new User();
//		u.setUsername("Tom");
//		user.findUser(u.getUsername());
		
		/*u.setUsername("haha");
		user.addUser(u.getUsername());*/
	}
}

運行結果:

 

進入方法---圍繞通知

>>>>>>>>准備搜查用戶..........

---------------【findAll】: {Smith=Smith00, Tom=Tom00, 小明=小明00, Lucy=Lucy00,Hello=Hello00} ------------------

退出方法---圍繞通知

>>>>>>>> 搜查用戶完成..........

 

注:@Before是在所攔截方法運行之前運行一段邏輯。@After是在所攔截方法運行之后運行一段邏輯。@Around是能夠同一時候在所攔截方法的前后運行一段邏輯。

 

以上是針對注解的方式來實現。那么配置文件也一樣,僅僅須要在applicationContext.xml中加入例如以下代碼:

<!--  <aop:config>
		<aop:pointcut id="find" expression="execution(* com.tgb.spring.aop.*.find*(..))" />
		<aop:pointcut id="add" 	expression="execution(* com.tgb.spring.aop.*.add*(..))" />
		
		<aop:aspect id="checkUser" ref="check">
			<aop:before method="beforeCheck" pointcut-ref="find"/>
			<aop:after method="afterCheck" pointcut-ref="find"/>
		</aop:aspect>
		
		<aop:aspect id="checkAdd" ref="check">
			<aop:before method="beforeAdd" pointcut-ref="add"/>
			<aop:after method="afterAdd" pointcut-ref="add"/>
		</aop:aspect>
	
	</aop:config>-->

總結:

 

以上是簡介了一下怎樣使用Spring AOP,在使用的過程中也加深我們對AOP思想的理解。事實上AOP就是要我們實現熱插拔效果,下篇會繼續介紹Spring AOP的實現原理。

 

附:在使用過程中注意JDK版本號與易用的aspectJrt的版本號問題





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM