SpringAOP总结

AOP概念介绍

AOP:(Aspect Oriented Programming)面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

特点:
1.依赖动态代理实现功能的统一维护;
2.AOP是面向的对象编程的补充,将系统中和主要业务无关的代码提取出来封装到一个类中(代码块中),将封装后的类或者代码块成为切面。
3.纵向重复,横向抽取。
4.降低主要业务和辅助业务的耦合度,同时可以提高代码的重用性。

在总结AOP相关内容之前先介绍一下代理以及动态代理的概念

代理:一个机构或者人代理另外一个人或者另外一个机构完成一部分工作。一个方法或者类代理另外一个方法或者另外一个类完成一部分其他辅助业务,降低主要业务和辅助业务的耦合度,同时通过辅助业务可以对主要业务增强。

静态代理:为每一个目标类(要被代理的类)创建一个代理类,静态代理中代理类在编译期就已经确定,静态代理的效率相对动态代理来说相对高一些,但是静态代理代码冗余大。

动态代理:根据不同的目标类(要被代理的类)通过反射在内存中动态生成一个代理类,动态代理则是JVM运行时动态生成,可以最大限度的降低代码的冗余。

常用的动态代理有两种JDK代理和CGLib代理。

JDK代理

代理的目标类实现了接口(代理类和目标类实现相同的接口)
完全依赖反射来实现代理功能,不需要外部依赖包

public class JDKProxy {
	/*
	 *  为目标类生产代理类的方法
	 */
	public Object getProxy(Object tarObj) {
		/*
		 * 参数一:目标类的类加载器
		 * 参数二:目标类实现的接口
		 *参数三:InvocationHandler: 代理类对象执行方法时内存中执行的内容
		 */
		return Proxy.newProxyInstance(tarObj.getClass().getClassLoader(), tarObj.getClass().getInterfaces(), new InvocationHandler() {
			
			/*
			 * 参数一:代理类对象
			 * 参数二:目标类的方法Method对象
			 *参数三:目标类的方法参数
			 */
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// TODO Auto-generated method stub
				//执行目标类的主要业务
				Object res = method.invoke(tarObj, args);
				//辅助业务
				System.out.println("提交事务");
				return res;
			}
		});
	}
}

CGLib代理

对代理目标类可以实现接口(代理类和目标类实现相同的接口)也可以是没有实现接口的目标类(代理类继承目标类)。
加入依赖包:asm-5.0.4.jar cglib-3.2.4.jar

public class CGLibProxy {
	/*
	 *  为目标类生产代理类的方法
	 */
	public Object getProxy(Object tarObj) {
		Enhancer en=new Enhancer();
		en.setClassLoader(tarObj.getClass().getClassLoader());//目标类的类加载器
		//en.setInterfaces(tarObj.getClass().getInterfaces());//目标类实现的接口
		en.setSuperclass(tarObj.getClass());
		en.setCallback(new MethodInterceptor() {
			
			@Override
			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
				// TODO Auto-generated method stub
				//执行目标类的主要业务
				Object res = method.invoke(tarObj, args);
				//辅助业务
				System.out.println("提交事务");
				return res;
			}
		});//代理类对象执行方法时内存中执行的内容
		return en.create();
	}
}

SpringAOP配置

1、连接点:需要增强的方法
2、切点:方法被增强以后成为切点。
3、通知:增强的内容成为通知。
4、切面:把通知作用在切点上形成切面(通知+切点)。
5、织入:把通知作用在切点上过程称为织入的过程。
6、目标类:要被代理(增强)的类
7、代理类:含有增强的内容的类

以XML方式完成SpringAOP的配置

SpringAOP配置步骤:
1.加入依赖包:aspectjtools-1.8.4.jar,aopalliance-1.0.jar,spring-aspects-4.3.6.RELEASE.jar
2.准备目标类(UserService,UserServiceImpl)
3.准备代理类以及增强的内容(辅助业务)
4.织入的完成:把代理类中的辅助业务作用在目标类中方法上
在Spring的配置文件中配置如下
在这里插入图片描述
指定切点的语法
expression=execution(访问修饰 返回值类型 方法名(参数))
访问修饰:(非必须),可以省略不写支持任何访问修饰符
返回值类型:,任意返回值类型
方法名:包名(任意一级包,…包中所有内容).类名().方法名(

参数:(…任意参数)
案例:
execution( * com.offcn.service2..(…)):com.offcn.service2包中的任意类任意方法
execution( * com.offcn.service2…*(…)):com.offcn.service2包中的任意类或者任意包中的任意方法。

通知:
前置通知:辅助业务在主要业务之前执行。
后置通知:辅助业务在主要业务之后执行,当主要业务中出现异常,辅助业务不执行,在辅助业务中可以得到主要业务执行后的返回值。
最终通知:辅助业务在主要业务之后执行,不管主要业务中是否出现异常,辅助业务都会执行
异常通知:辅助业务在主要业务之后执行,只有在主要业务出现异常时,辅助业务才会执行。
环绕通知:辅助业务可以在主要业务之前执行,辅助业务也可以在主要业务之厚执行,辅助业务也可以在主要业务之前,之后都执行。

以注解的方式完成aop的配置

1.spring配置文件中开启注解扫描

<!-- 开启注解扫描 -->
<context:component-scan base-package="com.fly.service"></context:component-scan>
<!-- 启用aop自动代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2目标类只用于注解实例化
在这里插入图片描述
3代理类
使用Component注解实例化代理类
使用Aspect注解设置为切面类
在这里插入图片描述

在辅助业务的方法上通过注解指定切点的范围
在辅助业务的方法上通过注解指定切点的范围

原文链接:加载失败,请重新获取