Spring中AOP概念理解:
- AOP是面向切面编程的英文缩写,AOP实质就是对Java动态代理规范并把其中的精华进行提炼和升华。
AOP中的概念:
1.切面:增强的功能
2.连接点:业务函数,这个函数加入了切面的功能
3.切入点:连接点的集合,有零个或多个连接点.切入点表示切面的执行位置。
这三个概念可以理解为:你的电脑内存不够了,你想增加内存,你就会去某网上买内存条(切面),买回来你就需要安装到电脑内存的接口上即可(连接点)。一般的电脑外加内存条都是在原有的基础上追加的,那么现在把思维扩展一下,如果我新买的内存条安装在原有内存的前面或者后面,那么这个前后的位置就是切入点。因为操作系统都是从内存的开始到结束读取文件的,那么如果新的内存条安装在前那么它就会先读取新内存条的文件。反之同理。将这个例子映射到程序代码中:就是一段代码从上往下执行,你想要你使用的功能函数(连接点)增强一下功能(切面),那么在它执行前(后)执行你增强的功能就是切入点了。
了解了AOP的概念那么现在就用代码来实现AOP,我使用的是Aspectj框架实现的。在使用这个框架之前先了解一下Aspectj框架中的切入点表达式:
表达式原型:
其中表达式中加了[]的部分可以表示可省略
execution(
[modifiers-patterm] 访问权限
ret-type-patterm 返回值类型
[declaring-type-patterm] 全限定类名
name-patterm(param-patterm)函数名(参数类型和参数个数)
[throws-patterm]抛出异常类型
)
表达式中的匹配符号:
符号 | 意义 |
---|---|
* | 0至多个任务 |
…(两个点) | 用于函数参数中,表示任意多个参数。用在包名后,表示当前包及其子包路径 |
+ | 用在类名后,表示当前类及其子类。用来接口后,表示当前接口及其实现类 |
使用Aspectj框架实现AOP
- 项目目录:
- 在pom.xml文件中添加依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
- 在MyAspect类中:
/*切面类:是用来给业务函数增强功能的
*@Aspect:是aspectj框架中,表示当前类是切面类
* 位置:在类定义的上面使用
* */
@Aspect
public class MyAspect {
/**定义函数实现功能增强,函数的定义格式
* 1.public函数
* 2.一般都是void返回值,环绕通知模块除外
* 3.函数名称自定义
* 4.函数可以有参数,参数类型有限制
*
* @Before:前置通知
* 属性:value表示切入点表达式,表示切面执行的位置(即目标函数)
* 位置:函数定义上面
* 特点:
* 1.在目标函数之前执行
* 2.不会影响目标函数的执行
* 3.不会改变目标函数的执行结果
* */
@Before(value="execution(* com.bjpowernode.service.ServiceImpl.doSome())")
public void myBefore(){
/**实现功能增强
* */
System.out.println("前置通知:目标函数之前,执行日志功能");
}
}
- application-config.xml文件中:
<!--声明目标类对象-->
<bean id="someServiceTarget" class="com.bjpowernode.service.ServiceImpl"/>
<!--声明切面类对象-->
<bean id="myAspect" class="com.bjpowernode.aspect.MyAspect"/>
<!--声明自动代理生成器:使用aspectj把Spring容器中目标类对象生成代理-->
<aop:aspectj-autoproxy/>
- Java测试代码:
public static void main(String[] args){
String config="application-config.xml";
ApplicationContext context=new ClassPathXmlApplicationContext(config);
/**从Spring容器中获取目标对象(代理对象)
* */
Service service=(Service) context.getBean("someServiceTarget");
/**通过代理执行业务函数,实现功能的增强
* */
service.doSome();
}