SpringAop

OOD面向对象设计
OOP 面向对象编程
AOP 面向切面编程:  面向切面编程  一种编程范式,指导开发者如何组织程序结构

OOP和AOP 区别:
1、AOP弥补了OOP的不足,基于OOP基础之上进行横向开发
2、OOP规定程序开发以类为主体模型,一切围绕对象进行,完成某个任务先构建模型
3 、AOP程序开发主要关注基于OOP开发中的共性功能,一切围绕共性功能进行,完成某个任务先构建可能遇到的所有共性功能(当所有功能都开发出来也就没有共性与非共性之分)
AOP好处?
	1、 提高代码的可重用性
	2、 业务代码编码更简洁
	 3 、业务代码维护更高效
	4 、业务功能扩展更便捷
AOP 核心概念?
	1 、连接点(Joinpoint):   所有方法(可能要)
	2、切入点(PointCut):   共性方法
	3、通知(advice):   增强() 共性功能
	4、切面(Aspect):   切入点和通知的关系, Aop类中增强方法
	5、通知类型
	6、目标对象(target):  对象所属类
	7、织入(Weaving);  共性功能进入原始功能 动态
	8、代理(Proxy):   原始对象所属类的增强
	AOP运行原理:
	Spring容器加载配置文件,监控所有配置的切入点方法的执行
	当监控到切入点方法被运行时,使用代理机制,动态创建目标对象的代理对象,根据通知类型,在代理对象的对应位置将对应的功能织入,完成完整的代码逻辑并运行
AspectJ框架它定义的通知类型有61.aop:before 前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行,应用 数据校验
	2.after-returning   后置通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行,  应用:返回值相关数据处理
	3.after-throwing   抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行:  应用:对原始方法中出现的异常信息进行处理
    4.aop:after  最终通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知                 应用:现场清理
	5.around   环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行 应用:十分强大,可以做任何事情

配置

AspectJ框架它定义的通知类型有61.	前置通知Before 相当于BeforeAdvice
	2.	后置通知AfterReturning 相当于AfterReturningAdvice
	3.	环绕通知 Around 相当于MethodInterceptor
	4.	抛出通知AfterThrowing 相当于ThrowAdvice
	5.	引介通知DeclareParents 相当于IntroductionInterceptor
	6.	最终通知After 不管是否异常,该通知都会执行
相比spring 的传统AOP Advice多了一个最终通知


接入步骤基于xml实现
	
1.编写目标类

public class UserServiceImpl implements IUserService {
	@Override
	public void add() {
		System.out.println("userService add...");
	}

	@Override
	public String del() {
		System.out.println(10 / 0); // 一定会抛出异常
		System.out.println("userService del...");

		return "hello world";
	}
}


2.创建通知类

	public class UserServiceHelper {

		/* 
		 *前置通知
		 *
		 *	方法名称需要在xml文件中配置
		 *	<aop:before method="before" pointcut-ref="delPointCut"/>
		 */ 
		public void before() {
			System.out.println("前置通知");
		}

		/* 
		 *后置通知
		 *
		 *	方法名称需要在xml文件中配置
		 *	<aop:after-returning method="afterReturning" pointcut-ref="delPointCut"/>
		 *	returning返回的val要和参数里的val名称要一致
		 */ 
		public void afterReturning() {
			System.out.println("后置通知");
		}

		/* 
		 *环绕通知
		 *
		 *	方法名称需要在xml文件中配置
		 *	<aop:around method="around"  pointcut-ref="delPointCut"/>
		 */ 
		public Object around(ProceedingJoinPoint pjp) throws Throwable {
		
			System.out.println("环绕前....");

			Object value = pjp.proceed(); // 执行目标行为

			System.out.println("环绕后....");

			return value;
		}

		/* 
		 *异常抛出通知
		 *
		 *	方法名称需要在xml文件中配置
		 *	<aop:after-throwing method="afterThrowing" pointcut-ref="delPointCut" throwing="ex"/>
		 *	throwing的ex要和方法里的参数ex一致
		 */ 
		public void afterThrowing(Throwable ex) {
			System.out.println("发现了异常。。。。"+ex);
		}

		/* 
		 *最终通知
		 *
		 *	方法名称需要在xml文件中配置
		 *	
		 */ 
		public void after() {
			System.out.println("最终通知");
		}
	}
	
3.在applicationContext.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:context="http://www.springframework.org/schema/context"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
			 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

		<!-- target原始目标类 -->
		<bean id="userService" class="cn.itheima.aspectj.UserServiceImpl"/>
		
		<!-- advice通知-->
		<bean id="userServiceAdvice" class="cn.itheima.aspectj.UserServiceHelper"/>
		
		<!-- 使用aop:config来声明开启  使用aop:aspect来配置切面 -->
		<!--
			Proxy-target-class默认值是false,代表的是如果目标是有接口的使用JDK动态代理,如果没有接口使用cglib.
			proxy-target-class="true"	代表使用cglib动态代理
		-->
		<aop:config proxy-target-class="true">
			<!-- 切入点-->
			<aop:pointcut expression="execution(* 具体包名.service.*.*(..))" id="delPointCut"/>
			<aop:aspect ref="userServiceAdvice">
				<!-- 前置通知 -->
				<aop:before method="before" pointcut-ref="delPointCut"/>
				<!-- 后置通知 -->
				<aop:after-returning method="afterReturning" pointcut-ref="delPointCut"/>
				<!-- 环绕通知 -->
				<aop:around method="around"  pointcut-ref="delPointCut"/>
				<!-- 抛出异常通知 -->
				<aop:after-throwing method="afterThrowing" pointcut-ref="delPointCut" throwing="ex"/>
				<!-- 最终通知 -->
				<aop:after method="after" pointcut-ref="delPointCut"/>
			</aop:aspect>
		</aop:config>
	</beans> 
	
	注意:

		<aop:config proxy-target-class="true">
			<aop:aspect ref="userServiceAdvice">
				<!--
					<aop:pointcut expression="execution(* *.del(..))" id="delPointCut"/>
					<aop:before method="before" pointcut-ref="delPointCut"/>
				-->
				<!-- 下面和上面2行的作用一致 -->
				<aop:before method="before" pointcut="execution(* *.del(..))"
			</aop:aspect>
		</aop:config>

		
切点表达式:
	
关于execution语法常用:

	1.	execution(* com.b3a4a.aop.service.*.*(..)) IOrderService接口中定义的所有方法



注解接入步骤


1.在配置文件applicationContext.xml中配置bean扫描和开启aspectj注解自动代理

	<?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:aop="http://www.springframework.org/schema/aop"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
		
		<!-- bean扫描 -->
		<context:component-scan base-package="com.b3a4a" />

		<!-- 
			开启aspectj注解自动代理 
			proxy-target-class="true"	代表使用cglib动态代理
		-->
		<aop:aspectj-autoproxy proxy-target-class="true"/>
	</beans> 
	



2.编写目标类

	@Service
	public class UserServiceImpl implements IUserService {
		@Override
		public void add() {
			System.out.println("userService add...");
		}

		@Override
		public String del() {
			//System.out.println(10 / 0); // 一定会抛出异常
			System.out.println("userService del...");
			return "hello world";
		}
	}


3.编写增强类

	@Component
	@Aspect // 声明当前的bean就是一个切面
	public class UserServiceImplHelper {
		// 前置通知
		@Before("execution(* *.add(..))")
		public void before() {
			System.out.println("前置通知...");
		}

		// 后置通知
		@AfterReturning("execution(* *.add(..))")
		public void afterReturning(JoinPoint jp, Object value) {
			System.out.println("后置通知,目标方法的返回是" + value);
		}

		// 环绕通知
		@Around("execution(* *.add(..))")
		public Object around(ProceedingJoinPoint pjp) throws Throwable {
			System.out.println("环绕前...");
			Object value = pjp.proceed();
			System.out.println("环绕后");
			return value;
		}

		// 异常抛出通知
		@AfterThrowing(value = "execution(* *.del(..))", throwing = "ex")
		public void afterThrowing(JoinPoint jp, Throwable ex) {
			System.out.println("异常抛出通知:" + ex);
		}

		// 最终通知
		@After("execution(* *.add(..))")
		public void after() {
			System.out.println("最终通知");
		}
	}

		
切点表达式:
	
关于execution语法常用:

	1.	execution(* com.b3a4a.aop.service.*.*(..)) IOrderService接口中定义的所有方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值