一、AOP基本概念
什么是AOP?
AOP Aspect-Oriented Programming 面向切面编程,我更喜欢它的另一种翻译面向方面编程(将一方面一方面的业务逻辑增强到原有业务逻辑的方式)。它是一种编程思想能使软件简单,容易维护,更加容易被复用的一种编程方式;AOP只是OOP编程方式的一种补充,并非什么新的技术。
AOP编程方式解决问题的关键在于对关注点的抽象。对系统中的一些分散在多个不相关业务模块中的共同问题(关注点),将这些关注点从各个业务模块中抽象出来是AOP编程的精髓。如日志记录功能,事务管理功能,方法的性能分析等功能从系统业务模块的分离。
对于OOP和AOP的的主要开发流程做一个对比:
OOP 编程基本流程
1)归纳分析系统,抽象领域模型;
2)使用class 来封装领域模型,实现类的功能;
3)把各个类相互协作,组装形成一个完整的功能。
AOP 编程基本流程
1)归纳分析系统中的关注点;
2)分离方面对象,使用OOP 将这些方面封装成一个公用的类;
3)织入到业务功能,按配置织入规则将切面对象(织入或集成)到系统功能中,形成一个增强后的功能。
二、AOP中的一些关键的专业术语
1)关注点:就是系统中要解决的问题。比如在电子商务系统中,安全验证、日志记录等都属于关注点(Core Concerns);
2)切面(Aspect):用来组织多个Advice,负责管理切入点和增强的关系;
3)增强(Advice):定义何时在切入点执行“织入关注点”;如,在执行方法前执行before,在执行方法后执行after等等。
4)连接点(Joinpoint):明确的某一个被织入代码的点,如方法调用,异常抛出,方法返回等等时间点;
5)切入点(cutpoint):可以织入增强方法的连接点。当连接点满足被增强的要求时,会在该连接点添加增强,此时的连接点就成为切入点。
6)织入(weaving) :织入是指把解决横切问题的切面模板,与系统中的其它核心模块通过一定策略或规则组合到一起的过程;具体的技术方案有:a.动态代理;b.类加载器织入c.编译器织入:AspectJ主要就是是使用这种织入方式
三、AOP的具体的流程示意图
四、代码实现
4.1项目目录
4.2EmpDao接口类
package com.emp.dao;
public interface EmpDao {
public int addEmp();
}
4.3EmpDaoImpl实现类
package com.emp.dao;
public class EmpDaoImpl implements EmpDao {
@Override
public int addEmp() {
// TODO Auto-generated method stub
System.out.println("添加员工成功");
return 0;
}
}
4.4EmpLoggerService切面类
package com.emp.service;
public class EmpLoggerService{
public void writeEmp() {
System.out.println("日志记录成功");
}
}
4.5测试类
package com.emp.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.emp.dao.EmpDao;
import com.emp.dao.EmpDaoImpl;
public class MainTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("springaop.xml");
EmpDao service = (EmpDao) ctx.getBean("empService");
service.addEmp();
}
}
4.6springaop.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="empService" class="com.emp.dao.EmpDaoImpl"></bean>
<bean id="empLoggerService" class="com.emp.service.EmpLoggerService" />
<!--
AOP配置详细介绍:
1) <aop:aspect ref="empLoggerService">
指向一个方面的类的spring bean 对应 public class OptLogger
2)<aop:after method="writeEmp" pointcut="" />配置增强行为,在切入点之后执行aspect中的方法
3)切入点规则解释:
a.第一个*代表返回值为所有类型,后面跟着空格
b. com.iflytek.. 注意两个点,代表在com.iflytek下的所有子包中
c.*Service代表所有所有的Service结尾的类,为什么是类不是包呢?因为它紧跟着的是方法。
d.*(..)所有方法 -->
<!--方式一:把二者写在一起 -->
<aop:config>
<!-- aspect 指向记录日志功能的bean -->
<aop:aspect ref="empLoggerService">
<!-- after增强,method指向日志功能bean中的要增强方法,在pointcut切入点执行前执行增强方法writeEmp -->
<aop:after method="writeEmp"
pointcut="execution(* com.emp.dao.EmpDaoImpl.*(..))" />
</aop:aspect>
</aop:config>
<!--方式二:先定义切入点,再使用pointcut-ref引用 -->
<aop:config>
<aop:pointcut expression="execution(* com.emp.dao.EmpDaoImpl.*(..))" id='point'/>
<aop:aspect ref="empLoggerService">
<aop:after method="writeEmp" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
<!--其他增强行为,感兴趣自己可以去体验下:
<aop:after/>:在切入点执行之后执行
<aop:after-returning/>:在切入点返回后执行
<aop:after-throwing/>:在切入点抛出异常后执行
<aop:around/>:在切入点开始和结束之后都执行
<aop:before/>:在切入点执行前执行
-->
</beans>
4.7相关架包
https://pan.baidu.com/s/1i-XJUXL5a_5uP_FiAbzpNA