一、spring框架的AOP概念
Spring 框架的一个关键组件是面向方面的编程(AOP)框架。面向方面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点。跨一个应用程序的多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。
这个概念可能会很抽象,但你只需要知道AOP相当于一个拦截器用来拦截方法或者程序,你可以在方法执行之前或者之后添加额外的功能就可以。
二、AOP相关术语
相关术语
通知的类型(切入类型)
- 前置通知 <aop:before ></aop:before>:在一个方法执行之前,执行通知。
- 后置通知<aop:after ></aop:after>:在一个方法执行之后,不考虑其结果,执行通知。
- 返回后通知<aop:after-returning ></aop:after-returning>:在一个方法执行之后,只有在方法成功完成时,才能执行通知。
- 抛出异常后通知<aop:after-throwing ></aop:after-throwing>:在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知
- 环绕通知<aop:around ></aop:round>:在建议方法调用之前和之后,执行通知。
三、实例(存取款业务)
1、相关类目录
2、BankDao(Check、EmpDao可以不要)
package sc.dao;
public interface BankDao {
//转账
public void remirt();
//存钱
public void save();
}
3、AdminCheck
package sc.impl;
import sc.dao.Check;
public class AdminCheck implements Check{
public void check(){
System.out.println("权限验证开始");
}
}
4、BankDaoImpl(EmpDaoImpl不要)
package sc.impl;
import sc.dao.BankDao;
public class BankDaoImpl implements BankDao{
@Override
public void remirt() {
System.out.println("转账的业务");
}
@Override
public void save() {
System.out.println("存钱的业务");
}
}
5、logManager
package sc.impl;
public class LogManager {
public void writelog(){
System.out.println("日志正在写入");
}
}
6、TransactionManager
package sc.impl;
public class TransactionManager {
public void begin(){
System.out.println("开始业务逻辑");
}
public void commit(){
System.out.println("提交业务逻辑");
}
}
7、spring.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-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
">
<bean id="adminCheck" class="sc.impl.AdminCheck"></bean>
<bean id="transactionManager" class="sc.impl.TransactionManager"></bean>
<bean id="logManager" class="sc.impl.LogManager"></bean>
<bean id="bankDao" class="sc.impl.BankDaoImpl"></bean>
<bean id="empDao" class="sc.impl.EmpDaoImpl"></bean>
<!--开始spring aop 面向切面-->
<aop:config>
<!--切入点-->
<aop:pointcut id="service" expression="execution(* sc.impl.*.*(..))"></aop:pointcut>
<aop:aspect ref="adminCheck">
<!--在此之前切入-->
<aop:before method="check" pointcut-ref="service"></aop:before>
</aop:aspect>
<aop:aspect ref="transactionManager">
<aop:before method="begin" pointcut-ref="service"></aop:before>
</aop:aspect>
<!--after method 用于那个方法是最终通知 谁在最前面 最后输出就在最后 -->
<aop:aspect ref="logManager">
<aop:after method="writelog" pointcut-ref="service"></aop:after>
</aop:aspect>
<aop:aspect ref="transactionManager">
<aop:after method="commit" pointcut-ref="service"></aop:after>
</aop:aspect>
</aop:config>
</beans>
8、test
package sc.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import sc.dao.BankDao;
import sc.dao.Check;
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
BankDao bankDao = (BankDao) ac.getBean("bankDao");
bankDao.remirt();
System.out.println("----------------------");
bankDao.save();
}
}
运行结果为
这样可以减少代码的冗余,你会发现只写了一次验证开始、开始业务逻辑、提交业务逻辑、日志正在写入,但可以使用两次。