1. 程式人生 > >面向切面程式設計的兩種實現

面向切面程式設計的兩種實現

1、面向切面的定義自行百度

2、面向切面程式設計的應用場景自己想象,大概就是日誌之類的地方

3、上面兩句話基本是廢話

實現方式一,在XML中宣告切面

1、編寫一個原始類

package com.hsb.beans;

import org.springframework.stereotype.Repository;

@Repository
public class Perform {
	public void show(){
		System.out.println("message from Perform.show()");
	}
}
本例中show()方法就是切點。在一個大型專案中,許多個切點構成了切面,這些切面實際上是為了某些共同的東西而成為一個面的。
2、編寫一個切面類
package com.hsb.aop;

import org.aspectj.lang.ProceedingJoinPoint;

public class Audience {
	public void beforeShow(){
		System.out.println("message from beforeShow");
	}
	public void afterShow(){
		System.out.println("message from afterShow");
	}
	public void around(ProceedingJoinPoint joinpoint){
		System.out.println("message from Start around");
		long start = System.currentTimeMillis();
		try {
			joinpoint.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("message from End around total : "+(end-start)+" ms");
	}
}

注意程式碼中的joinpoint.proceed(),這句話就是實際呼叫切點方法,也就是本例中的show()。如果切面類中定義了around通知,通知一定要加上這句話,否則要切點方法不會被呼叫!此處應該是一個坑,一定要記住,免得後面找bug到處都找不到。

3、配置XML

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
                        http://www.springframework.org/schema/aop   
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
                        http://www.springframework.org/schema/tx   
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
                        http://www.springframework.org/schema/context   
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd"
	default-lazy-init="true">
	<context:component-scan base-package="com.hsb.beans" />
	<bean id="audience" class="com.hsb.aop.Audience" />
	<aop:config>
		<aop:aspect ref="audience">
			<aop:pointcut expression="execution(* com.hsb.beans.Perform.show(..))"
				id="performance" />
			<aop:before method="beforeShow" pointcut-ref="performance" />
			<aop:after method="afterShow" pointcut-ref="performance" />
			<aop:around method="around" pointcut-ref="performance" />
		</aop:aspect>
	</aop:config>
</beans>
注意,上面的<bean id="audience" class="com.hsb.aop.Audience" />將切面類生命為一個bean,而<aop:config></aop:config>宣告中引用了這個bean.簡單解釋一下<aop:config>宣告中各句的意思。配置宣告的時候,一定注意使用英文字元進行配置,不然會報很多稀奇古怪的錯誤,大致就是說切面無法使用或者其他什麼的。
<aop:pointcut expression="execution(* com.hsb.beans.Perform.show(..))"
				id="performance" />
聲明瞭一個切點(pointcut),後面宣告的通知會引用。

通知一共有五種分別是<aop:before />、<aop:after />、<aop:after-returning />、<aop:after-throwing />、<aop:around />。根據其字面意思大概就能懂其應用場景,而around上面已經說過了,標識出切點位置,在切點前後做某些工作。

4、測試

package com.hsb.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.hsb.beans.Perform;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:**/applicationContext.xml","classpath*:**/springmvc-servlet.xml"})
public class PerformTests {
	@Autowired
	private Perform perform;

	@Test
	public void testShow() {
		perform.show();
	}

}
上面的程式碼使用自動注入生成一個Perform例項,在測試方法中呼叫切點方法show().

5、Console列印結果

九月 05, 2016 9:54:03 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from file [D:\PractiseForWork\WorkSpace\HelloMaven\target\classes\applicationContext.xml]
九月 05, 2016 9:54:04 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
資訊: Refreshing [email protected]3c1e69: startup date [Mon Sep 05 21:54:04 CST 2016]; root of context hierarchy
message from beforeShow
message from Start around
message from Perform.show()
message from End around total : 38 ms
message from afterShow
從Console的列印結果中,我們可以猜測出五種通知的具體用法

6、Maven工程一定要新增依賴

                <dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.12</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.6.12</version>
		</dependency>
如果不新增上述依賴,極有可能會測試報錯。



實現方式二,註解切面

1、編寫一個原始類

package com.hsb.beans;

import org.springframework.stereotype.Repository;

@Repository
public class Perform {
	public void show(){
		System.out.println("message from Perform.show()");
	}
}
2、編寫一個切面類
package com.hsb.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;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Audience {
	@Pointcut("execution(* com.hsb.beans.Perform.show(..))")
	public void performance() {
	}

	@Before("performance()")
	public void beforeShow() {
		System.out.println("message from beforeShow");
	}

	@After("performance()")
	public void afterShow() {
		System.out.println("message from afterShow");
	}

	@Around("performance()")
	public void around(ProceedingJoinPoint joinpoint) {
		System.out.println("message from Start around");
		long start = System.currentTimeMillis();
		try {
			joinpoint.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("message from End around total : " + (end - start)
				+ " ms");
	}
}
@Aspect將此類宣告為切面類,@Component將此類宣告為bean放到spring容器中,@Pointcut將下面的performance宣告為一個切點,並將Perform中的show()方法進行了關聯。execution(* com.hsb.beans.Perform.show(..))的意思是,執行此方法時,忽略返回值,引數型別和個數忽略。還可以更加簡寫,用於匹配合適的方法,譬如對Perform類的全部方法進行匹配就是com.hsb.beans.Perform.*。

3、配置xml

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
                        http://www.springframework.org/schema/aop   
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
                        http://www.springframework.org/schema/tx   
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
                        http://www.springframework.org/schema/context   
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd"
	default-lazy-init="true">
	<context:component-scan base-package="com.hsb.*" />
	<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
可以看見此處就沒有使用<aop:config />宣告,而是使用<aop:aspectj-autoproxy proxy-target-class="true" />。這句話的意思是自動在spring上下文中建立一個AnnotationAwareAspectJAutoProxyCreator類,它會自動代理一些bean,這些bean的方法需要與使用@Aspect註解的bean中所定義的切點相匹配,而這些切點又是使用@Pointcut註解定義出來的。proxy-target-class="true"的意思是使用基於類的代理使用cglib庫,如果為false則使用jdk自帶的基於介面的代理

4、測試

package com.hsb.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.hsb.beans.Perform;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:**/applicationContext.xml","classpath*:**/springmvc-servlet.xml"})
public class PerformTests {
	@Autowired
	private Perform perform;

	@Test
	public void testShow() {
		perform.show();
	}

}

5、Console列印結果
九月 05, 2016 10:24:46 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from file [D:\PractiseForWork\WorkSpace\HelloMaven\target\classes\applicationContext.xml]
九月 05, 2016 10:24:47 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
資訊: Refreshing [email protected]3c1e69: startup date [Mon Sep 05 22:24:47 CST 2016]; root of context hierarchy
message from Start around
message from beforeShow
message from Perform.show()
message from End around total : 39 ms
message from afterShow

如上所示,完全是一樣的效果。可以看出使用註解減少了很多工作,不容易出錯,各個元件間的耦合度降低了。試想,如果一個大型專案中有很多切面,切點,如果全部去xml中配置,將會是一項極為艱苦的工作,但是如果使用註解就可以做很少的工作完成這一切。

後記一、使用註解時一定要使用@component或者@Repository、@Controller、@Service中一個去宣告,將切面類放入到spring容器中,不然就去xml中顯式寫一個bean,不然的話就會報錯,無法實現切面功能。

相關推薦

面向切面程式設計實現

1、面向切面的定義自行百度 2、面向切面程式設計的應用場景自己想象,大概就是日誌之類的地方 3、上面兩句話基本是廢話 實現方式一,在XML中宣告切面 1、編寫一個原始類 package com.hsb.beans; import org.springframework

詳解Spring面向切面程式設計(AOP)三實現

一、什麼是AOP AOP(Aspect Oriented Programming),即面向切面程式設計,可以說是OOP(Object Oriented Programming,面向物件程式設計)的補充和完善。OOP引入封裝、繼承、多型等概念來建立一種物件層次結構,用於模擬公共行為的一個集合。不過OOP允許開

Java框架之Spring AOP 面向切面程式設計 有哪幾實現方式?如何選擇適合的AOP實現方式?

文章目錄 1. 實現方式 2. JDK動態代理如何實現? 2.1 主要的實現過程 3. 如何選擇? 1. 實現方式 JDK 動態代理實現和 cglib 實現 2. JDK

【小家java】POP(面向過程程式設計)、OOP(面向物件程式設計)、AOP(面向切面程式設計)三程式設計思想的區別和聯絡

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

Spring之註解實現aop(面向切面程式設計)

1:Aop(aspect object programming)面向切面程式設計,名詞解釋:     1.1:功能:讓關注點程式碼與業務邏輯程式碼分離     1.2:關注點       

Spring面向切面程式設計(AOP)原理一之使用JDK實現動態代理

什麼是面向切面程式設計? AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP(面向物件程式設計)的延續,是軟體開發中的一個熱點,也是Spr

Spring之面向切面程式設計(AOP)四通知

面向切面程式設計(AOP)面向切面的程式設計:指很多功能都有重複的程式碼,把這些重複的程式碼獨立出來實現,再在執行的時候動態加入“切面類程式碼”。AOP是一種設計思想,和具體的程式碼實現無關。優點:      A、把共性功能和核心業務功能解耦。      B、共性程式碼的複用

面向切面程式設計(3):AOP實現機制

1 AOP各種的實現   AOP就是面向切面程式設計,我們可以從幾個層面來實現AOP,如下圖。 圖1 AOP實現的不同層面   在編譯器修改原始碼,在執行期位元組碼載入前修改位元組碼或位元組碼載入後動態建立代理類的位元組碼,以下是各種實現機制的比較。  類別

Spring AOP(面向切面程式設計)小demo實現

Spring AOP1、目的:Spring AOP的存在是為了解耦,AOP可以讓一組類共享相同的行為。在OOP(面向物件程式設計)中,一般是通過繼承類和實現介面等方式實現一組類共享某一相同的行為,java中類只能單繼承,阻礙了更多行為新增到一組類上,AOP彌補了以上不足。2、

Spring學習筆記 —— AOP(面向切面程式設計) 之使用ProxyFactoryBean實現AOP

引言 到上一篇文章Spring學習筆記 —— Spring Context為止,我們已經基本瞭解Spring中的基本物件——Bean——的建立、相關屬性的注入以及獲取。其實在這不難發現,Spring的容器設計與Java的物件設計之間是有相似的地方的,

Java實現AOP面向切面程式設計的例項教程

介紹 眾所周知,AOP(面向切面程式設計)是Spring框架的特色功能之一。通過設定橫切關注點(cross cutting concerns),AOP提供了極高的擴充套件性。那AOP在Spring中是怎樣運作的呢?當你只能使用core java,卻需要AOP技術時,這個問題的解答變得極為關鍵。不僅如此,

Spring面向切面程式設計的三方式以及常用相關案例總結

Spring面向切面程式設計 ================================================== spring面向切面程式設計的方法之一:實現介面方式 1.執行前增強:MethodBeforeAdvice介面 標示方法:public vo

JS實現AOP(面向切面程式設計--裝飾者模式)

1、AOP:主要作用是把一些跟核心業務邏輯模組無關的功能抽離出來,這些跟業務邏輯無關的功能通常包括日誌統計、安全控制、異常處理等。把這些功能抽離出來之後,再通過“動態織入”的方式參入業務邏輯模組中。 2、AOP好處 保證業務邏輯模組的純淨和高內聚性 方便複用日誌統計等功

採用DBUtil框架實現AOP(面向切面程式設計)對事務的處理

專案中個檔案的結構: 1。導包: commons-dbcp-1.4.jar commons-dbutils-1.4.jar commons-pool-1.5.6.jar mysql-connector-java-5.0.8-bin.jar 2.d

基於SpringBoot AOP面向切面程式設計實現Redis分散式鎖

![](https://img2020.cnblogs.com/other/1815316/202007/1815316-20200708094430273-1467040799.png) **基於SpringBoot AOP面向切面程式設計實現Redis分散式鎖** **基於SpringBoot AOP面

[譯]如何在ASP.NET Core中實現面向切面程式設計(AOP)

> 原文地址:[ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE](https://blog.zhaytam.com/2020/08/18/aspnetcore-dynamic-proxies-for-aop/) > 原文作者:ZANID HA

左邊固定,右邊自適應布局的實現

定位 abs red logs light 正常 idt blue mar html結構: <body> <div class="left"></div> <div class="right"></div

easyui combobox 三級級聯 input 實現

data edit pat adc inpu idt cts wid req /**<img src=‘${pageContext.request.contextPath}/images/block.png‘/> * @param 默認載入 省市 */

CSS3實現五子棋Web小遊戲,Canvas畫布和DOM實現,並且具有悔棋和撤銷悔棋功能。

posit oct padding 角色 sar pac osi fse ech 用Canvas實現五子棋的思路: 1、點擊棋盤,獲取坐標x,y,計算出棋子的二維數組坐標i和j, 2、棋子的實現,先arc一個圓,再填充漸變色。 3、下完一步棋後切換畫筆和角色。 4、贏法算法

[轉]Web APi之認證(Authentication)實現方式【二】(十三)

用戶數 ted das 客戶 元素 基礎 目標 開始 net 本文轉自:http://www.cnblogs.com/CreateMyself/p/4857799.html 前言 上一節我們詳細講解了認證及其基本信息,這一節我們通過兩種不同方式來實現認證,並且分析如