AOP入門

AOP簡介:java

  面向切面的編程(也叫面向方面編程):Aspect Oriented Programming(AOP),是軟件開發中的一個熱點,也是 Spring框架中的一個重要內容。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,AOP是OOP編程的延續。spring

與OOP的區別:express

   面向對象編程主要用於爲同一對象層次的公用行爲建模。它的弱點是將公共行爲應用於多個無關對象模型之間。而這偏偏是面向方面編程適合的地方。有了 AOP,咱們能夠定義交叉的關係,並將這些關係應用於跨模塊的、彼此不一樣的對象模型。AOP 同時還可讓咱們層次化功能性而不是嵌入功能性,從而使得代碼有更好的可讀性和易於維護。它會和面向對象編程合做得很好。編程


 舉個例子:app


學生的service類框架

public class StudentServiceImpl implements IStudentService{

	@Override
	public void addStudent(String name) {
		// TODO Auto-generated method stub
		System.out.println("姓名:"+name);
	}

}



 如今有個需求:在添加方法的邏輯中,添加以前輸出日誌,添加完成以後輸出添加成功日誌,最簡單的方法是:ide

public class StudentServiceImpl implements IStudentService{

	@Override
	public void addStudent(String name) {
		// TODO Auto-generated method stub
		
		//輸出日誌邏輯代碼
		
		System.out.println("姓名:"+name);
		
		//添加成功日誌代碼
	}

}


如今咱們又有別的Service 類也須要一樣的需求。須要修改的類足足有100個(開個玩笑) ,不可能一個個去修改,Service類,並且倆個輸出日誌的代碼在其餘Service類中是同樣的,若是一直複製粘貼對代碼沒有作到可複用性。測試

這個時候AOP就派上用處了。spa


以Spring框架中爲例:代理

 spring.xml中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" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">


	<context:component-scan base-package="com.younchen.*" />


	<bean id="StudentImpl" class="com.younchen.aop.StudentImpl" />
        <bean id="DaliyLog" class="com.younchen.aop.DaliyLog"/> 
        <bean id="Log" class="com.younchen.aop.Log"/>

	<aop:config>
		<!-- expression 括號 第一個 星號表示 全部返回值類型,第二個星號表示全部類,第三個星號表示全部的方法,括號倆點表示方法參數 -->
		<aop:pointcut expression="execution(* com.younchen.aop.*.*(..))"
				id="target" />
		<aop:aspect id="Logger" ref="Log">
			<aop:before method="beforeAdd" pointcut-ref="target" />
			<aop:after method="afterAdd" pointcut-ref="target" />
		</aop:aspect>
	</aop:config>
</beans>

 在config 標籤中的第一個標籤pointcut是切入點, expression是表達式, 看下括號中的第一個*號,意思是針對於全部的返回類型 ,緊接着是類所在的包名,以後的倆個星號分別表明類名和方法名 ,後面的括號中倆個點表明全部的參數。該標籤的做用是聲明在執行com.younchen.aop這個包下的全部類的全部方法時執行咱們要切入的方法 。

 aspect標籤是切面也就是咱們要切入的方法  ref指定咱們的切入方法的類,該標籤中的子標籤 before method的做用是expression表達式中指定的類的方法執行前執行, after method是以後執行。 pointcut-ref 是指定切入點,除了引用的切入點(表達式指定的範圍外) 該切面是不執行的。

未給出的完整代碼:

Log類:

package com.younchen.aop;

public class Log {

	
	public void beforeAdd(){
		System.out.println("準備添加數據");
	}
	
	public void afterAdd(){
		System.out.println("添加完成");
	}
}

SpringUtil類:

public class SpringUtil {

		private static ApplicationContext context = null;
		
		public static ApplicationContext getApplicationContext() {
			if (context == null) {
				context = new ClassPathXmlApplicationContext("spring.xml");
			}
			return context;
		}

		public static ApplicationContext getApplicationContext(String path) {
			return new ClassPathXmlApplicationContext(path);
		}

		public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {
			return new AnnotationConfigApplicationContext(basePackages);
		}
}

其餘service類:

public class DaliyLog {

	public void addLog(){
		System.out.println("添加每日日誌");
	}
}



測試類:

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	  ApplicationContext applicationContext=(ApplicationContext) SpringUtil.getApplicationContext("springaop.xml");
	  IStudent studentService=(IStudent) applicationContext.getBean("StudentImpl");
	  DaliyLog daliyLog=(DaliyLog) applicationContext.getBean("DaliyLog");
	  
	  studentService.addStudent("麥克米蘭");
	  System.out.println("-----------------------------------------------------------");
	  daliyLog.addLog();
	}
}

執行結果:

準備添加數據
姓名:麥克米蘭
添加完成
-----------------------------------------------------------
準備添加數據
添加每日日誌
添加完成


  以上是簡單一個例子,AOP的原理實際上是動態代理。 切面是被動態代理的類, 在被動態代理時,產生一個新的類,在這個類中除了執行被代理的方法外,還注入了切面的方法。

歡迎指正。

相關文章
相關標籤/搜索