Spring AOP 的兩種開發方式(附代碼鏈接)

最後附有網盤鏈接(程序打包+數據庫)

Spring AOP的開發

Spring AOP定義

①是一種編程範式,一種新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充。

②AOP 的主要編程對象是切面(aspect), 而切面模塊化橫切關注點。

③在應用 AOP 編程時, 仍然需要定義公共功能, 但可以明確的定義這個功能在哪裏, 以什麼方式應用, 並且不必修改受影響的類. 這樣一來橫切關注點就被模塊化到特殊的對象(切面)裏。

Spring AOP優點

①降低模塊耦合度
②使系統容易擴展
③更好的代碼複用性

Spring AOP術語

在這裏插入圖片描述

基於XML配置開發

1.相關jar包

spring-aop-4.3.3.RELEASE.jar,
aspectjweaver-1.8.5.jar
aspectjrt-1.8.5.jar

2.Spring XML配置文件

在resource文件裏面整個conifg文件夾,spring xml文件放裏面

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        ">
    <!--以上是類似於引文件,等相關配置-->
	<!-- 註冊業務BEAN -->

	<bean id="bankService" class="init.wuji.logger.BankServiceImpl">
	</bean>


	<bean id="loggerAspect" class="init.wuji.logger.LoggerAspect"></bean>


	<aop:config>
		<aop:pointcut expression="execution(* init.wuji.logger.*.*(..))" id="loggerPointCut"/>
		<!--包名.類名.方法名()  如果全類全方法就用*-->
		<aop:aspect ref="loggerAspect">
			<aop:before method="logerBefore" pointcut-ref="loggerPointCut"/>
		</aop:aspect>

	</aop:config>

</beans>

3.其他類文件的部署

我的是在init.wuji.logger包裏面整了這些類。

下面這是接口

package init.wuji.logger;

import java.math.BigDecimal;

public interface BankService {

	public BigDecimal transfer(String target, String source, BigDecimal money);
	
	
	public void test();
}

下面這是實現類

package init.wuji.logger;

import java.math.BigDecimal;

public class BankServiceImpl implements BankService{

	
	public BigDecimal transfer(String target, String source, BigDecimal money) {
		System.out.println(source + "向" + target + "轉賬:" + money);
		
		
		return new BigDecimal("12345612");
	}

	public void test() {
		System.out.println("=============BankServiceImpl=====test===========>");
	}

}

下面這是本文重點

package init.wuji.logger;

import org.aspectj.lang.JoinPoint;

public class LoggerAspect {

	
	public void logerBefore(JoinPoint jp) {
		String methodName = jp.getSignature().getName();
		System.out.println("method: " + methodName + "將要被執行!");
		
		Object[] args = jp.getArgs();
		for(Object arg : args) {
			System.out.println("=============參數:>" + arg);
		}
		
	}
	
}

main方法測試運行

package init.wuji.logger;

import java.math.BigDecimal;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext-xml-aop.xml");
		
		BankService bsp = ioc.getBean("bankService", BankService.class);
		
		bsp.transfer("張世交", "馬雲", new BigDecimal("100000000"));
		

	}

}

控制檯顯示結果爲

16:28:05.907 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bankService'
16:28:05.907 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
16:28:06.634 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'loggerAspect'
method: transfer將要被執行!
=============參數:>張世交
=============參數:>馬雲
=============參數:>100000000
馬雲向張世交轉賬:100000000

另外通知方法有多種,我只是給了一種前置通知還有
後置通知、返回通知、異常通知、環繞通知、與其類似。

其重大區別是 環繞通知很強力,權力大,可隱藏返回值
所以原方法有return,環繞通知必須也有return。

基於註解的開發

相關jar與xml開發一樣

Spring XML配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        ">
	<!-- 註冊業務BEAN -->

	<context:component-scan base-package="init.wuji.anno.springaop"></context:component-scan>
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 僅僅是在此處來了個自動掃描 -->
</beans>

logger類的編寫

//包名爲init.wuji.anno.springaop
通知類Java類編寫:使用@Aspect 和@Component標記爲切面的Spring Bean組件

package init.wuji.anno.springaop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnnoLoggerAspect {

	@Before("execution(* init.wuji.anno.springaop.*.*(..))")
	public void logerBefore(JoinPoint jp) {
		String methodName = jp.getSignature().getName();
		System.out.println("method: " + methodName + "將要被執行!");
		
		Object[] args = jp.getArgs();
		for(Object arg : args) {
			System.out.println("=============參數:>" + arg);
		}
		
	}
	
}

上面的代碼前置通知用的是@before(作用域)
後置通知則爲@After()
異常通知則爲@AffterThrowing()
環繞通知則爲@Around()

普通類

@Service()

package init.wuji.anno.springaop;

import java.math.BigDecimal;

import org.springframework.stereotype.Service;
@Service
public interface BankService {

	public BigDecimal transfer(String target, String source, BigDecimal money);
	
	
	public void test();
}

package init.wuji.anno.springaop;

import java.math.BigDecimal;

import org.springframework.stereotype.Service;
@Service("bankService")
public class BankServiceImpl implements BankService{

	
	public BigDecimal transfer(String target, String source, BigDecimal money) {
		System.out.println(source + "向" + target + "轉賬:" + money);
		
		
		return new BigDecimal("12345612");
	}

	public void test() {
		System.out.println("=============BankServiceImpl=====test===========>");
	}

}

主方法

package init.wuji.anno.springaop;

import java.math.BigDecimal;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext-anno-aop2.xml");
		
		BankService bsp = ioc.getBean("bankService", BankService.class);
		
		bsp.transfer("張世交", "馬雲", new BigDecimal("100000000"));
		

	}

}

運行結果

16:50:06.225 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bankService'
16:50:06.254 [main] DEBUG org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory - Found AspectJ method: public void init.wuji.anno.springaop.AnnoLoggerAspect.logerBefore(org.aspectj.lang.JoinPoint)
method: transfer將要被執行!
=============參數:>張世交
=============參數:>馬雲
=============參數:>100000000
馬雲向張世交轉賬:100000000

鏈接

鏈接:https://pan.baidu.com/s/1_8Hs6V06GdX7ia5fYV4MlQ
提取碼:7s8u

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章