1、AOP概念:java
面向切面编程(Aspect Oriented Programming)能够经过预编译方式和运行期动态代理实如今不修改源代码的状况下给程序动态统一添加功能的一种技术。能够说是OOP(面向对象编程)的补充和完善。spring
如下是AOP的几个概念:express
一、切面(Aspect ):简单的理解就是把那些与核心业务无关的代码提取出来,进行封装成一个或几个模块用来处理那些附加的功能代码,如日志、事物、安全验证。咱们把这个模块的做用理解为一个切面,其实切面就是咱们写的一个类,这个类中的代码原来是在业务模块完成的,如今单独成一个或几个类。在业务模块须要的时候才织入。编程
二、链接点(Joinpoint):在程序执行过程当中某个特定的点,好比某方法调用的时候或者处理异常的时候。在Spring AOP中,一个链接点老是表明一个方法的执行。经过声明一个JoinPoint类型的参数可使通知(Active)的主体部分得到链接点信息。安全
三、切入点(PointCut):本质上是一个链接点的结构。在AOP中,能够定义一个PointCut来捕获相关方法的调用。app
四、织入(Weaving):把切面(aspect)链接到其余的运用类型或者对象上,并建立一个被通知(advice)的对象。这些能够在编译时(如使用AspectJ编译器)、类加载时和运行时完成。Spring和其余纯Java AOP框架同样,在运行时完成织入。框架
五、通知(Advice):在切面某个特定的链接点上执行的动做。通知有各类类型,其中包括around、before和after等通知。通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器作通知模型,并维护一个链接点为中心链接链。函数
通知的类型:学习
(1) 、前置通知:在某链接点以前执行的通知,但这个通知不能阻止链接点前的执行(除非它抛出一个异常);测试
(2) 、返回通知:在某链接点正常完成后执行的通知,例如,一个方法没有任何抛出,正常返回。
(3) 、抛出异常后通知:在方法抛出异常退出时执行的通知。
(4) 、环绕通知:包括一个链接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知能够在方法调用先后完成自定义的行为。它也会执行是否继续执行链接点或直接返回它们本身的值或抛出异常来结束执行。
1、编写一个类封装用户的常见操做(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---");
}
}
2、编写一个检查用户是否合法的类。
package test4.aop;
//检查用户是否合法的类
public class CheckSecurity {
public void check(){
System.out.println("----check admin----");
}
}
3、改写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>
4、编写测试类:
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的文件头须要更新,因此文中写了全部的信息。