公司品牌网站建设价格低,东莞电商建站,上海市住宅建设发展中心网站,潍坊网站制作江门公司文章目录 Spring-AOP入门案例概念:通知(Advice)切入点(Pointcut )切面#xff08;Aspect#xff09; 目标对象(target)代理对象(Proxy)顾问#xff08;Advisor)连接点(JoinPoint) 简单需求#xff1a;在接口执行前输出当前系统时间Demo原始未添加aop前1 项目包结构2 创建相… 文章目录 Spring-AOP入门案例概念:通知(Advice)切入点(Pointcut )切面Aspect 目标对象(target)代理对象(Proxy)顾问Advisor)连接点(JoinPoint) 简单需求在接口执行前输出当前系统时间Demo原始未添加aop前1 项目包结构2 创建相关文件2.1 pom.xml2.2 创建BookDao类2.3 创建BookDaoImpl实现类2.4 创建MySpringConfig配置类2.5 创建DemoAop主启动类打印结果 Demo案例添加aop1 pom.xml引入相关的配置包2 把共性的方法抽取出来,定义一个新的类通知类切入位置绑定相关的业务方法3 配置类添加EnableAspectJAutoProxy4 启动主启动类未修改update原有方法已切入共性方法 项目中异常问题Repository注解报红需要引入Spring依赖或者直接引入springboot依赖方案解决一方案解决二 AOP注解综合概念使用Run方法获取class类反射class类1 使用注解2 读取配置文件 Spring-AOP入门案例
概念:
AOP为Aspect Oriented Programming的缩写,又被称为面向切面编程, 对接口进行动态代理需要引入切面框架Aspect,用AOP可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性同时提高了开发的效率;
不去动原来的代码而是基于原来代码产生代理对象通过代理的方法去包装原来的方法就完成了对以前方法的增强。换句话说AOP的底层原理就是动态代理的实现。应用场景一般应用在需要多个业务流程中都需要相同或类似的业务处理且与核心业务无关则特别适合用AOP技术来解决; 包括权限日志和持久化等等。通知(Advice)
前置增强、后置增强、环绕增强、异常抛出增强、引介增强等类型。
1前置增强org.springframework.aop.BeforeAdvice代表前置增强spring只支持方法级的增强目前可用MethodBeforeAdvice。
2后置增强org.springframework.aop.AfterReturningAdvice代表后置增强在目标方法执行后实施增强。
3环绕增强org.aopalliance.intercept.MethodInterceptor代表环绕增强在目标方法执行前后实施增强。
4异常抛出增强org.springframework.aop.ThrowsAdvice在目标方法执行抛出异常后实施增强。方法名必须为afterThrowing,
如参前三个可选最后一个是Throwable或其子类。
5引介增强org.springframework.aop.IntroductionInterceptor表示目标类添加一些新的方法和属性连接点是类级别而不是方法级别。如 在方法执行之前验证用户是否有效。 在方法执行之后打印方法的执行耗时。 在方法抛出异常后记录异常信息发送到mq。切入点(Pointcut )
用来指定需要将通知使用到哪些方法上 比如需要用在哪些类的哪些方法上切入点就是做这个配置的。
也可以把这个表达式理解为一个查询条件系统会根据这个查询条件查询到我们要进行增强的代码位置。切面Aspect
通知Advice和切入点Pointcut的组合。切面来定义在哪些地方Pointcut执行什么操作Advice。
简单地说就是将那些与业务无关却为业务模块所共同调用的逻辑或责任封装起来
便于减少系统的重复代码降低模块间的耦合度并有利于未来的可操作性和可维护性。
AOP代表的是一个横向的关系如果说“对象”是一个空心的圆柱体其中封装的是对象的属性和行为
那么面向方面编程的方法就仿佛一把利刃将这些空心圆柱体剖开以获得其内部的消息。
而剖开的切面也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原不留痕迹。目标对象(target)
目标对象指将要被增强的对象即包含主业务逻辑的类对象我们也称之为委托类。代理对象(Proxy)
AOP中会通过代理的方式对目标对象生成一个代理对象代理对象中会加入需要增强功能通过代理对象来间接的方式目标对象起到增强目标对象的效果。顾问Advisor)
Advisor 其实它就是 Pointcut 与 Advice 的组合Advice 是要增强的逻辑而增强的逻辑要在什么地方执行是通过Pointcut来指定的所以 Advice 必需与 Pointcut 组合在一起这就诞生了 Advisor 这个类spring Aop中提供了一个Advisor接口将Pointcut 与 Advice 的组合起来。Advisor有好几个称呼顾问、通知器。其中这4个连接点(JoinPoint)、通知(advise)、切入点(pointcut)、顾问advisor)在spring中都定义了接口和类来表示这些对象。连接点(JoinPoint)
就是SpringAOP通过告诉它的切入点的位置找的的具体的要增强的代码的位置这个代码位置就是连接点。连接点由两个信息确定 方法(表示程序执行点即在哪个目标方法) 相对点(表示方位即目标方法的什么位置比如调用前后等)简单来说连接点就是被拦截到的程序执行点因为Spring只支持方法类型的连接点所以在Spring中连接点就是被拦截到的方法。简单需求在接口执行前输出当前系统时间
开发模式可以XML 或者 注解进行实现
思路分析
1 导入坐标pom.xml2 制作连接方法Dao与实现类3 制作共性功能通知类与通知4 定义切入点5 绑定切入点与通知关系切面 Demo原始未添加aop前
1 项目包结构 2 创建相关文件
2.1 pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.test/groupIdartifactIdtest-maven-aop/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.6.2/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency/dependencies/project2.2 创建BookDao类
package com.test.dao;public interface BookDao {public void save();public void update();
}2.3 创建BookDaoImpl实现类
package com.test.dao.impl;import com.test.dao.BookDao;
import org.springframework.stereotype.Repository;Repository
public class BookDaoImpl implements BookDao{public void save() {System.out.println(System.currentTimeMillis());System.out.println(book dao save ...);}public void update() {System.out.println(book dao update ...);}
}2.4 创建MySpringConfig配置类
package com.test.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;Configuration
ComponentScan(com.test)
public class MySpringConfig {}2.5 创建DemoAop主启动类
package com.test;import com.test.config.MySpringConfig;
import com.test.dao.BookDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DemoAop {public static void main(String[] args) {AnnotationConfigApplicationContext ctx new AnnotationConfigApplicationContext(MySpringConfig.class);BookDao bookDao ctx.getBean(BookDao.class);bookDao.save(); // 当前的系统时间打印了// bookDao.update(); 需求执行这个方法需要执行打印系统时间不能修改update的原始方法/*** AnnotationConfigApplicationContext是spring中利用注解配置的方式构建spring上下文的类。* 对于具体使用参考https://www.cnblogs.com/javasl/p/11783484.html**/}}打印结果 Demo案例添加aop
1 pom.xml引入相关的配置包 dependenciesdependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.4/version/dependency/dependencies查看包依赖可以看到context包导入后aop就会导入了 2 把共性的方法抽取出来,定义一个新的类通知类切入位置绑定相关的业务方法 package com.test.aop;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;Component
Aspect
public class MyAdvice {// 定义切入点// 返回是void类型具体哪个方法Pointcut(execution(void com.test.dao.BookDao.update()))private void pt(){} // 空方法Before(pt())public void method() { // 共性功能System.out.println(System.currentTimeMillis());}/*第1定义共性方法切入的方法method(),还没有Before注解第3步加入的第2步 定义切入点Pointcut,当执行到pt(),执行切入点方法execution(void com.test.dao.BookDao.update())第3步 绑入切入点的之间关系 --在com.test.dao.BookDao.update()方法什么时候执行method()方法使用Before(“”)第4步 需要受到spring的管理component。定义bean加Aspect告诉spring当aop处理生效第5步 配置类中package com.test.config。MySpringConfig 通知这个类我是注解开发的EnableAspectJAutoProxy,这个启动了Aspect识别相关的Pointcut等注解*/
}3 配置类添加EnableAspectJAutoProxy
package com.test.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;Configuration
ComponentScan(com.test)
EnableAspectJAutoProxy
public class MySpringConfig {}4 启动主启动类未修改update原有方法已切入共性方法 项目中异常问题
Repository是属于Spring的注解。它用来标注访问层的类Dao层它表示一个仓库主要用于封装对于数据库的访问。其实现方式与Component注解相同只是为了明确类的作用而设立。
即Repository是Component注解的一个派生品与Service和Controller都可以理解为Component注解的扩展。他们的作用都是在类上实例化bean并把当前类对象的实现类交给spring容器进行管理。
Repository注解修饰哪个类表明这个类具有对数据库CRUD的功能用在持久层的接口上。Repository注解报红需要引入Spring依赖或者直接引入springboot依赖
方案解决一
propertiesmaven.compiler.source11/maven.compiler.sourcemaven.compiler.target11/maven.compiler.targetspring.version5.3.15/spring.version
/properties
!-- Spring --
dependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion${spring.version}/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion${spring.version}/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version
/dependency方案解决二
添加Web场景依赖
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency
/dependenciesAOP注解综合概念使用
/** * 日志切面类 */
Aspect //定义切面类
public class LogAnnotationAspect { SuppressWarnings(unused) //定义切入点提供一个方法这个方法的名字就是改切入点的id Pointcut(execution(* com.abc.service.*.*(..))) private void allMethod(){} //针对指定的切入点表达式选择的切入点应用前置通知 Before(execution(* com.abc.service.*.*(..))) public void before(JoinPoint call) { String className call.getTarget().getClass().getName(); String methodName call.getSignature().getName(); System.out.println(【注解-前置通知】: className 类的 methodName 方法开始了); } //访问命名切入点来应用后置通知 AfterReturning(allMethod()) public void afterReturn() { System.out.println(【注解-后置通知】:方法正常结束了); } //应用最终通知 After(allMethod()) public void after(){ System.out.println(【注解-最终通知】:不管方法有没有正常执行完成, 一定会返回的); } //应用异常抛出后通知 AfterThrowing(allMethod()) public void afterThrowing() { System.out.println(【注解-异常抛出后通知】:方法执行时出异常了); } //应用周围通知 //Around(allMethod()) public Object doAround(ProceedingJoinPoint call) throws Throwable{ Object result null; //相当于前置通知 this.before(call);try { result call.proceed();//相当于后置通知 this.afterReturn(); } catch (Throwable e) { //相当于异常抛出后通知 this.afterThrowing(); throw e; }finally{ //相当于最终通知 this.after(); } return result; }
}Run方法获取class类反射class类
1 使用注解
AnnotationConfigApplicationContext是spring中利用注解配置的方式构建spring上下文的类。
第一种方式构造函数传入一个或者多个类。可以是注解类也可以是普通类传入的类都会纳入到spring容器中。如下
第二种方式构造函数传入一个包名该包下的类都会创建bean并且纳入spring容器中
App.javaUser.class没有加注解不会创建bean
第三种方式构造函数传入一个加了ComponentScan注解的类该注解指明了扫描的包和排除掉的类参考文章https://www.cnblogs.com/javasl/p/11783484.html2 读取配置文件 使用XML创建bean参考文章https://zhuanlan.zhihu.com/p/572380275