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

发布了13 篇原创文章 · 获赞 0 · 访问量 288

猜你喜欢

转载自blog.csdn.net/weixin_43419816/article/details/103099729