济南网站建设力推搜点网络ok,wordpress 会员支付宝,淘宝怎么提高关键词搜索排名,全屋整装定制目录 1.AOP是什么?
2.案列#xff1a;
3.spring的aop的专业术语 4.代码模拟
4.1 前置通知 3.2.后置通知 3.3.环绕通知 3.4.异常通知 3.5.过滤通知 1.AOP是什么? 面向切面编程#xff08;Aspect-Oriented Programming#xff09;是一种编程范式#xff0c;它的主要… 目录 1.AOP是什么?
2.案列
3.spring的aop的专业术语 4.代码模拟
4.1 前置通知 3.2.后置通知 3.3.环绕通知 3.4.异常通知 3.5.过滤通知 1.AOP是什么? 面向切面编程Aspect-Oriented Programming是一种编程范式它的主要目的是通过预编译和运行期动态代理实现程序功能的横切cross-cutting特性如日志记录、性能统计、事务监控等。它可以帮助开发者将这些原本分散在各个方法或类中的业务逻辑抽象出来提高代码复用性降低耦合度面向切面编程的核心思想是将程序分为两个部分切入点和切面。切入点entry point是程序执行过程中需要被拦截的代码段而切面weaving则是实现横切功能的代码段。在运行时通过动态代理技术将切入点的代码交由切面织入实现横切的效果面向切面编程是希望能够将通用需求功能从不相关的类当中分离出来能够使得很多类共享一个行为一旦发生变化不必修改很多类而只是修改这个行为即可AOP通过提供另一种思考程序结构的方式来补充了面向对象编程OOP。OOP中模块化的基本单元是类(class)而AOP中模块化的基本单元是切面(aspect)。可以这么理解OOP是解决了纵向的代码复用问题AOP是解决了横向的代码复用问题. 2.案列 场景模拟这里我模拟的场景为线上书城系统 首先进行一个没有使用Aop的模拟代码展示 实体类Book其中是书籍的属性行为等
Dao类BookDao其中是有关于书籍操作的代码
业务逻辑层BookBiz...,BookBizImpl:...
Web层new 对象//增加
public int add(Book book) {
b.add()
}//修改
public int edit(Book book) {
b.edit()
}//删除
public int del(Book book) {
b.del()
}//上架
public int up(Book book) {
b.up()
}//下架
public int down(Book book) {
b.down()
} 但是很多时候会出现这样的情况 ①用户购买了书籍却说自己没有收到货物... ②店家发出的货物为空货物而其却为了牟利矢口否认... 针对这样的情况很多时候都没有证据来证明到底是真是假而在我们成熟的系统中通常都会添加一个叫做‘日志记录’的东西它可以用来记录和跟踪系统、应用程序或事件的活动和状态的过程通俗来说就是使用这个系统的用户的每一步操作都会被记录下来这样就话就成为一个证据那成熟的系统应该是怎么样 实体类Book其中是书籍的属性行为等
Dao类BookDao其中是有关于书籍操作的代码
业务逻辑层BookBiz...,BookBizImpl:...
Web层new对象//增加
public int add(Book book) {
b.add()
}//修改
public int edit(Book book) {
b.edit()
}//删除
public int del(Book book) {
b.del()
}//上架
public int up(Book book) {
datetime..//操作时的时间
username...//操作的用户名
args ...//参数
logBiz.add(datetime,username,args);//将其都添加到日志中去b.up()
}//下架
public int down(Book book) {
datetime..//操作时的时间
username...//操作的用户名
args ...//参数
logBiz.add(datetime,username,args);//将其都添加到日志中去b.down()
} 现在是在上架和下架中添加了日志记录如果要在其他的方法操作中也添加日志记录的话那就需要将这一段代码再重复几次这样就有点麻烦而且还改变了原有代码的结构如果需求发生改变需要对打印的日志内容作出修改那就必须修改用到了日志记录方法中的所有相关代码如果是1000个方法呢每次就需要手动去修改1000个方法中的代码对项目的维护成本就会很高这也不利于我们的系统维护。然后我们可以用到AOP可以帮助开发者将将原本分散在各个方法或类中的业务逻辑抽象出来提高代码复用性降低耦合度接下怎么提高代码的复用性 3.spring的aop的专业术语 项目代码但是从上往下依次执行而现在加入了面向切面的思想当我们的代码执行到目标对象是查看连接点是否有前置通知先执行前置通知再执行目标方法如果没有前置通知那么就直接执行目标方法最后看连接点上是否有后置通知如果有就再执行后置通知如果没有就执行完了。 连接点(Joinpoint)程序执行过程中明确的点如方法的调用或者异常的抛出. 目标(Target)被通知(被代理)的对象就是完成具体的业务逻辑 比如书籍的增删改查 通知(Advice)在某个特定的连接点上执行的动作同时Advice也是程序代码的具体实现例如一个实现日志记录的代码(通知有些书上也称为处理) 完成切面编程非业务核心代码 代理(Proxy)将通知应用到目标对象后创建的对象(代理目标通知), 例子外科医生护士只有代理对象才有AOP功能而AOP的代码是写在通知的方法里面的切入点(Pointcut)多个连接点的集合定义了通知应该应用到那些连接点 (也将Pointcut理解成一个条件 此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)比如给新增方法添加日志功能 适配器(Advisor)适配器通知(Advice)切入点(Pointcut) 注目标对象只负责业务逻辑代码 通知对象负责AOP代码这二个对象都没有AOP的功能只有代理对象才有。 4.代码模拟
4.1 前置通知 首先我们先写service接口和实现类进行模拟在里面写两个方法
package com.sy.aop.biz;public interface IBookBiz {// 购书public boolean buy(String userName, String bookName, Double price);// 发表书评public void comment(String userName, String comments);
}然后写实现类,重新这两个方法并且做了一个价格的判断
package com.sy.aop.biz.impl;import com.sy.aop.biz.IBookBiz;
import com.sy.aop.exception.PriceException;public class BookBizImpl implements IBookBiz {public BookBizImpl() {super();}public boolean buy(String userName, String bookName, Double price) {// 通过控制台的输出方式模拟购书if (null price || price 0) {throw new PriceException(book price exception);}System.out.println(userName buy bookName , spend price);return true;}public void comment(String userName, String comments) {// 通过控制台的输出方式模拟发表书评System.out.println(userName say: comments);}}接下来要写上面价格判断的异常
package com.sy.aop.exception;public class PriceException extends RuntimeException {public PriceException() {super();}public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public PriceException(String message, Throwable cause) {super(message, cause);}public PriceException(String message) {super(message);}public PriceException(Throwable cause) {super(cause);}}然后我们先创建一个类将类名.方法名携带的参数作为日志存储到数据库。
package com.sy.aop.advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;
import java.util.Arrays;/*** 买书、评论前加系统日志* author shenyan**/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// 在这里可以获取到目标类的全路径及方法及方法参数然后就可以将他们写到日志表里去String target arg2.getClass().getName();String methodName arg0.getName();String args Arrays.toString(arg1);System.out.println(【前置通知系统日志】target.methodName(args)被调用了);}}最后进行一个配置
!--aop--
!-- 目标对象 --
bean classcom.sy.aop.biz.impl.BookBizImpl idbookBiz/bean!-- 通知 --
bean classcom.sy.aop.advice.MyMethodBeforeAdvice idmethodBeforeAdvice/bean!-- 代理目标通知 --bean classorg.springframework.aop.framework.ProxyFactoryBean idbookProxyproperty nametarget refbookBiz/propertyproperty nameproxyInterfaceslistvaluecom.sy.aop.biz.IBookBiz/value/list/propertyproperty nameinterceptorNameslistvaluemyMethodBeforeAdvice/value/list/property/bean
前台的一个验证
package com.sy.aop.demo;import com.sy.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** author 谌艳* site www.shenyan.com* create 2023-08-17 21:13*/
public class demo1 {public static void main (String [] args){ClassPathXmlApplicationContext contextnew ClassPathXmlApplicationContext(spring-context.xml);IBookBiz bookBiz(IBookBiz) context.getBean(bookBiz);bookBiz.buy(花花,天下掉下一个林妹妹,18.88);bookBiz.comment(嘿嘿,嘿嘿嘿真好看);}
}结果为展示 3.2.后置通知 有了前面的铺垫直接再创建一个后置通知的类比起前置通知多了一个参数就是返回参数
package com.sy.aop.advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;
import java.util.Arrays;/*** 买书、评论前加系统日志* author shenyan**/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// 在这里可以获取到目标类的全路径及方法及方法参数然后就可以将他们写到日志表里去String target arg2.getClass().getName();String methodName arg0.getName();String args Arrays.toString(arg1);System.out.println(【前置通知系统日志】target.methodName(args)被调用了);}}接着配置文件即可然后前台看结果;
package com.sy.aop.demo;import com.sy.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** author 谌艳* site www.shenyan.com* create 2023-08-17 21:13*/
public class demo1 {public static void main (String [] args){ClassPathXmlApplicationContext contextnew ClassPathXmlApplicationContext(/spring-context.xml);
// IBookBiz bookBiz(IBookBiz) context.getBean(bookBiz);IBookBiz bookBiz(IBookBiz) context.getBean(bookProxy);bookBiz.buy(花花,天下掉下一个林妹妹,18.88);bookBiz.comment(嘿嘿,嘿嘿嘿真好看);}
}3.3.环绕通知 结合了前置通知和后置通知它两个都有所以一般常用这个 它只有一个参数但是这一个参数相当于上面前置通知和后置通知的34个参数
package com.sy.aop.advice;import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;import java.util.Arrays;/*** 环绕通知* 包含了前置和后置通知* * author shenyan**/
public class MyMethodInterceptor implements MethodInterceptor {Overridepublic Object invoke(MethodInvocation arg0) throws Throwable {String target arg0.getThis().getClass().getName();String methodName arg0.getMethod().getName();String args Arrays.toString(arg0.getArguments());System.out.println(【环绕通知调用前】target.methodName(args)被调用了);
// arg0.proceed()就是目标对象的方法Object proceed arg0.proceed();System.out.println(【环绕通知调用后】该方法被调用后的返回值为proceed);return proceed;}}接着就是配置文件 然后前台测试 结果展示 3.4.异常通知 先建一个类但是注意这个异常通知的类重写的话方法名字只能是这个否则报错
然后配置文件 然后在前台测试 结果展示 3.5.过滤通知 过滤通知就是那个适配器它不需要再建一个类直接再配置文件里面配置就可以了需要正则判断这里举例过滤的是后置通知 结果展示 今天小编的分享就结束呐生活总是需要不断去学习新的知识多想想然后再去实操持之以恒经验和思维都会发生转变我们要保持谦虚学习和自信的态度各位加油