Spring AOP编程
一、AOP概念:
面向切面编程(Aspect Oriented Programming)可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。可以说是OOP(面向对象编程)的补充和完善。
以下是AOP的几个概念:
1、切面(Aspect ):简单的理解就是把那些与核心业务无关的代码提取出来,进行封装成一个或几个模块用来处理那些附加的功能代码,如日志、事物、安全验证。我们把这个模块的作用理解为一个切面,其实切面就是我们写的一个类,这个类中的代码原来是在业务模块完成的,现在单独成一个或几个类。在业务模块需要的时候才织入。
2、连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是代表一个方法的执行。通过声明一个JoinPoint类型的参数可以使通知(Active)的主体部分获得连接点信息。
3、切入点(PointCut):本质上是一个连接点的结构。在AOP中,可以定义一个PointCut来捕获相关方法的调用。
4、织入(Weaving):把切面(aspect)连接到其他的运用类型或者对象上,并创建一个被通知(advice)的对象。这些可以在编译时(如使用AspectJ编译器)、类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
5、通知(Advice):在切面某个特定的连接点上执行的动作。通知有各种类型,其中包括around、before和after等通知。通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型,并维护一个连接点为中心连接链。
通知的类型:
(1) 、前置通知:在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常);
(2) 、返回通知:在某连接点正常完成后执行的通知,例如,一个方法没有任何抛出,正常返回。
(3) 、抛出异常后通知:在方法抛出异常退出时执行的通知。
(4) 、环绕通知:包括一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会执行是否继续执行连接点或直接返回它们自己的值或抛出异常来结束执行。
AOP Spring示例一
一、编写一个类封装用户的常见操作(UserDao.java)。
package test4.aop;
//封装用户常见的操作类
public class UserDao {
public void save(String name){
System.out.println("-----save user----");
}
public void delete(){
System.out.println("----delete user---");
}
public void update(){
System.out.println("----update user---");
}
}
二、编写一个检查用户是否合法的类。
package test4.aop;
//检查用户是否合法的类
public class CheckSecurity {
public void check(){
System.out.println("----check admin----");
}
}
三、改写Spring配置文件实现AOP(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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx " http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 以下是实现AOP面向切面编程的配置 -->
<bean id="checkbean" class="test4.aop.CheckSecurity"></bean>
<bean id="userDao" class="test4.aop.UserDao"/>
<aop:config>
<!-- 创建一个切面Aspect引用了bean "checkbean" -->
<aop:aspect id="security" ref="checkbean">
<!-- 声明一个切入点 当调用以public 声明的所有函数时 -->
<!--execution(public * *(..))表达式*之前必须有一个空格-->
<aop:pointcut id="allAddMethod" expression="execution(public * *(..))"/>
<!-- 当执行到切入点时,会在执行切入点之前调用bean "checkbean"中"check"函数 -->
<aop:before method="check" pointcut-ref="allAddMethod"/>
</aop:aspect>
</aop:config>
</beans>
四、编写测试类:
package test4;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test4.aop.UserDao;
public class Test {
//测试面向切面编程
@SuppressWarnings("resource")
public static void main(String[] args) {
/**读取Spring配置文件,创建一个bean工厂**/
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = (UserDao)factory.getBean("userDao");
dao.save("zhou");
}
}
总结:在学习书本知识的时候,发现书中的表达式是错误的,经过度量找到关于切入点语法定义,解决了问题。
参考:https://blog.csdn.net/corbin_zhang/article/details/80576809
注意:applicationContext.xml的文件头需要更新,所以文中写了所有的信息。