建个人网站,建网站的过程,wordpress升级500,wordpress 标签 彩色一#xff1a;AOP概念的引入
首先我们来看一下登录的原理 如上图所示这是一个基本的登录原理图#xff0c;但是如果我们想要在这个登录之上添加一些新的功能#xff0c;比如权限校验 那么我们能想到的就有两种方法#xff1a; ①#xff1a;通过对源代码的修改实现 ②AOP概念的引入
首先我们来看一下登录的原理 如上图所示这是一个基本的登录原理图但是如果我们想要在这个登录之上添加一些新的功能比如权限校验 那么我们能想到的就有两种方法 ①通过对源代码的修改实现 ②不通过修改源代码方式添加新的功能 AOP
二AOP相关的概念
1. AOP的概述
什么是AOP的技术 在软件业AOP为Aspect Oriented Programming的缩写意为面向切面编程 AOP是一种编程范式隶属于软工范畴指导开发者如何组织程序结构。 AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范。 通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术 AOP是OOP的延续是软件开发中的一个热点也是Spring框架中的一个重要内容是函数式编程的一种衍生范型。 利用AOP可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性同时提高了开发的效率。 AOP采取横向抽取机制取代了传统纵向继承体系重复性代码事务管理、安全检查、缓存 为什么要学习AOP可以在不修改源代码的前提下对程序进行增强
2. AOP的优势
运行期间不修改源代码的情况下对已有的方法进行增强 优势
减少重复的代码提供开发的效率维护方便
3. AOP的底层原理
JDK的动态代理技术 1、为接口创建代理类的字节码文件 2、使用ClassLoader将字节码文件加载到JVM 3、创建代理类实例对象执行对象的目标方法 cglib代理技术 为类生成代理对象被代理类有没有接口都无所谓底层是生成子类继承被代理类。
三Spring的AOP技术-配置文件方式
1. AOP相关的术语
Joinpoint(连接点) 类里面有哪些方法可以增强这些方法称为连接点 Pointcut(切入点) – 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义 Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能) Aspect(切面)-- 是 切入点通知 的结合以后咱们自己来编写和配置的
2. 基本准备工作
AspectJ是一个面向切面的框架它扩展了Java语言。AspectJ定义了AOP语法,AspectJ实际上是对AOP编程思想的一个实践.
3. AOP配置文件方式的入门
创建maven项目坐标依赖
dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.0.2.RELEASE/version/dependencydependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.0.2.RELEASE/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.12/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency!--AOP联盟--dependencygroupIdaopalliance/groupIdartifactIdaopalliance/artifactIdversion1.0/version/dependency!--Spring Aspects--dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion5.0.2.RELEASE/version/dependency!--aspectj--dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.8.3/version/dependency
/dependencies创建被增强的类
// 被增强的类
public class User {//连接点/切入点public void add(){System.out.println(add......);}public void update(){System.out.println(update......);}
}将目标类配置到Spring中
bean iduser classcom.aopImpl.User/bean定义切面类
public class UserProxy {//增强/通知 ---》前置通知public void before(){System.out.println(before.............);}
}在配置文件中定义切面类
bean iduserProxy classcom.aopImpl.UserProxy/bean在配置文件中完成aop的配置
!--配置切面--
aop:config!--配置切面 切入点 通知组成--aop:aspect refuserProxy!--前置通知UserServiceImpl的save方法执行前会增强--!--pointcut后边是切入点表达式作用是知道对对面的那个方法进行增强--aop:before methodbefore pointcutexecution(public void com.aopImpl.User.add())//aop:aspect
/aop:config完成测试
public class DemoTest {Testpublic void aopTest1(){ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);User user (User) applicationContext.getBean(user);user.add();}
}4. 切入点的表达式
再配置切入点的时候需要定义表达式具体展开如下 切入点表达式的格式如下 execution([修饰符] [返回值类型] [类全路径] [方法名 ( [参数] )]) 修饰符可以省略不写不是必须要出现的。 返回值类型是不能省略不写的根据你的方法来编写返回值可以使用 * 代替。 包名类名方法名参数的规则如下
例如com.qcby.demo3.BookDaoImpl.save()
首先包名类名方法名是不能省略不写的但是可以使用 * 代替
中间的包名可以使用 * 号代替
类名也可以使用 * 号代替也有类似的写法*DaoImpl
方法也可以使用 * 号代替
参数如果是一个参数可以使用 * 号代替如果想代表任意参数使用 ..比较通用的表达式execution(* com.qcby.*.ServiceImpl.save(..))
举例2com.qcby.demo3.BookDaoImpl当中所有的方法进行增强
execution(* com.qcby.*.ServiceImpl.*(..))
举例3com.qcby.demo3包当中所有的方法进行增强
execution(* com.qcby.*.*.*(..))!--配置切面--
aop:config!--配置切面 切入点 通知组成--aop:aspect refuserProxy!--切入点的表达式execution() 固定的写法public 是可以省略不写的方法的返回值 int String 通用的写法可以编写 * 不能省略不写的包名类名 不能省略不写的编写 * com.*方法名称 add() 可以写 *参数列表 (..) 表示任意类型和个数的参数比较通用的表达式execution(* com.*.User.add(..))--aop:before methodbefore pointcutexecution(* com.*.User.add(..))//aop:aspect
/aop:config5. AOP的通知类型
①: 前置通知 目标方法执行前进行增强。
如上配置案例就是前置通知
② 环绕通知 目标方法执行前后都可以进行增强。目标对象的方法需要手动执行。
// 环绕通知
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println(before.............);// 执行被增强的方法proceedingJoinPoint.proceed();System.out.println(after.............);
}xml配置
aop:around methodaround pointcutexecution(* com.*.User.add(..))/③. 最终通知 目标方法执行成功或者失败进行增强。
// 最终通知
public void after() {System.out.println(after.............);
}xml配置
aop:after methodafter pointcutexecution(* com.*.User.add(..))/④. 后置通知 目标方法执行成功后进行增强。
//后置通知
public void afterReturning() {System.out.println(afterReturning.............);
}xml配置
aop:after-returning methodafterReturning pointcutexecution(public void com.aopImpl.User.add())/⑤. 异常通知 目标方法执行失败后进行增强。(发生异常的时候才会执行否则不执行)
//异常通知
public void afterThrowing() {System.out.println(afterThrowing.............);
}需要改动一下切点
//连接点/切入点
public void add(){int a 10 / 0;System.out.println(add......);
}xml配置
aop:after-throwing methodafterThrowing pointcutexecution(public void com.aopImpl.User.add())/4.Spring的AOP技术-注解方式
1. AOP注解方式入门程序
创建maven工程导入坐标。编写接口完成IOC的操作。步骤略。 编写切面类 给切面类添加注解 Aspect编写增强的方法使用通知类型注解声明 ①.配置xml扫描注解
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd!--开启注解扫描--context:component-scan base-packagecom.aopImpl/context:component-scan/beans②.配置注解
Component
public class User {//连接点/切入点public void add(){System.out.println(add......);}
}给切面类添加注解 Aspect编写增强的方法使用通知类型注解声明
Component
Aspect //生成代理对象
public class UserProxy {}③.配置文件中开启自动代理
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd!--开启注解扫描--context:component-scan base-packagecom.aopImpl/context:component-scan!--开启Aspect生成代理对象--aop:aspectj-autoproxy/aop:aspectj-autoproxy/beans④.通知类型注解 Before – 前置通知 AfterReturing – 后置通知 Around – 环绕通知目标对象方法默认不执行的需要手动执行 After – 最终通知 AfterThrowing – 异常抛出通知
Component
Aspect //生成代理对象
public class UserProxy {//增强/通知 ---》前置通知Before(value execution(* com.*.User.add(..)))public void before(){System.out.println(before.............);}// 环绕通知Around(value execution(* com.*.User.add(..)))public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println(before.............);// 执行被增强的方法proceedingJoinPoint.proceed();System.out.println(after.............);}// 最终通知After(value execution(* com.*.User.add(..)))public void after() {System.out.println(after.............);}//异常通知AfterThrowing(value execution(* com.*.User.add(..)))public void afterThrowing() {System.out.println(afterThrowing.............);}//后置通知AfterReturning(value execution(* com.*.User.add(..)))public void afterReturning() {System.out.println(afterReturning.............);}
}
⑤.测试类
Test
public void aopTest1(){ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);user.add();
}