Spring切面之一

举报
tea_year 发表于 2021/12/30 00:05:01 2021/12/30
【摘要】 JAVA就业套餐课:https://edu.csdn.net/combo/detail/1230       为什么要使用AOP,在编写程序的时候,除了不必关心依赖的组件如何实现,在实际开发过程中,还需要将程序中涉及的公共问题集中解决。AOP是Aspect-Oriented...

JAVA就业套餐课:https://edu.csdn.net/combo/detail/1230      

为什么要使用AOP,在编写程序的时候,除了不必关心依赖的组件如何实现,在实际开发过程中,还需要将程序中涉及的公共问题集中解决。AOP是Aspect-Oriented Programming的简称,意思是面向切面编程。是对OOP的补充和完善,比如在开发中,所有的业务方法都需要日志记录、参数验证、事务处理,这些公共的处理如果放在每个业务方法中,系统会变的十分臃肿,即使写成公用类进行调用,也很难维护。散步在系统各处的需要在实现业务系统时关注的事情被称为“切面”,也称之为关注点,AOP的思想就是把这些公用部分从业务方法中提取出来,集中处理

AOP将软件系统分为两个部分:核心关注点和横切关注点。术语:

1切面:Aspect:切面是系统中抽象出来的某一个模块。

2.连接点:JoinPoint:程序执行过程中某个特定的点,如调用某方法或处理异常时,在SpringAOP中,连接点总是代表着某个方法的执行。

3.通知:Advice:通知是切面具体实现,是放置”切面代码的“类。

4.切入点:PointCut:多个连接点组成一个切入点,可以使用切入点表达式表示。

5.目标对象:Target Object:包含一个连接点的对象,即被拦截的对象。

6.AOP代理:AOP Proxy:AOP框架产生的对象,是通知和目标对象的结合体。

7.织入:Weaving:将切入点和通知结合的过程称之为织入。


  
  1. package com.sp.IC;
  2. import com.sp.bean.OutOfStockException;
  3. //手机业务接口
  4. public interface PhoneBiz {
  5. public void buyPhone(int num);//购买手机;
  6. public void salePhone(int num) throws OutOfStockException;//销售手机
  7. }

 

 


  
  1. package com.sp.bean;
  2. import com.sp.IC.PhoneBiz;
  3. public class PhoneBizImpl implements PhoneBiz{
  4. //库存属性;
  5. int num=140;
  6. public void buyPhone(int num) {
  7. System.out.println("手机进货"+num+"部");
  8. }
  9. public void salePhone(int num) throws OutOfStockException{
  10. if(this.num<num){
  11. throw new OutOfStockException("库存不足,客户需要"+num+"部手机,库存只有"+this.num+"部");
  12. }
  13. System.out.println("手机销售"+num+"部");
  14. }
  15. }

 


  
  1. package com.sp.bean;
  2. public class OutOfStockException extends Exception {
  3. //缺货异常;
  4. public OutOfStockException(String msg){
  5. super(msg);
  6. }
  7. }

 

 


  
  1. package com.sp.bean;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import org.aspectj.lang.JoinPoint;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. //通知类;
  7. public class LogAspect {
  8. //前置通知;
  9. public void before(JoinPoint jp)throws Throwable{
  10. Object[]args=jp.getArgs(); //目标方法所有参数;
  11. String methodName=jp.getSignature().getName(); //获得目标方法名称;
  12. if("buyPhone".equals(methodName)){
  13. System.out.println(currentTime()+"即将进行进货操作,数量为:"+args[0]);
  14. }
  15. if("salePhone".equals(methodName)){
  16. System.out.println(currentTime()+"即将进行销售操作,数量为:"+args[0]);
  17. }
  18. }
  19. //***********************后置通知***********************
  20. public void afterReturning(JoinPoint jp)throws Throwable{
  21. String methodName=jp.getSignature().getName();//获得签名方法的名字;
  22. if("buyPhone".equals(methodName)){
  23. System.out.println(currentTime()+"进货操作完毕");
  24. }
  25. if("salePhone".equals(methodName)){
  26. System.out.println(currentTime()+"销售操作完毕");
  27. }
  28. }
  29. public void after(JoinPoint jp)throws Throwable{
  30. String methodName=jp.getSignature().getName();
  31. if("buyPhone".equals(methodName)){
  32. System.out.println(currentTime()+"进货操作完毕,异常也要执行完毕的最终通知...");
  33. }
  34. if("salePhone".equals(methodName)){
  35. System.out.println(currentTime()+"销售操作完毕,异常也要执行完毕的最终通知...");
  36. }
  37. }
  38. //环绕通知;
  39. public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
  40. String method=pjp.getSignature().getName();
  41. long begin=System.currentTimeMillis();//当前时间;
  42. System.out.println(currentTime()+":"+method+"方法开始执行,计时开始!");
  43. try {
  44. return pjp.proceed();
  45. }finally{
  46. long end=System.currentTimeMillis();
  47. System.out.println(currentTime()+":"+method+"方法执行完毕,耗时:"+(end-begin)+"毫秒");
  48. }
  49. }
  50. //***********************后置通知结束*********************
  51. public void afterThrowing(JoinPoint jp,OutOfStockException e){
  52. String methodName=jp.getSignature().getName();
  53. System.out.println(currentTime()+methodName+"方法执行,发生缺货异常"+e.getMessage());
  54. }
  55. //输出时间的方法;
  56. public String currentTime(){
  57. SimpleDateFormat sdf=new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
  58. return sdf.format(new Date());
  59. }
  60. }

 


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  13. <!-- 目标业务对象 -->
  14. <bean id="phoneBiz" class="com.sp.bean.PhoneBizImpl"></bean>
  15. <!-- 日志管理切面类 -->
  16. <bean id="logAspectBean" class="com.sp.bean.LogAspect"></bean>
  17. <!-- Aop配置 -->
  18. <aop:config>
  19. <aop:pointcut expression="execution(void *Phone(int))" id="p1"/>
  20. <!-- 配置日志管理切面 -->
  21. <aop:aspect id="logAspect" ref="logAspectBean">
  22. <!-- 配置日志记录前置通知 -->
  23. <aop:before method="before" pointcut-ref="p1"/>
  24. <!-- 配置日志记录后置通知 -->
  25. <aop:after method="afterReturning" pointcut-ref="p1"/>
  26. <!-- 配置日志记录异常通知; -->
  27. <aop:after-throwing method="afterThrowing" pointcut-ref="p1" throwing="e"/>
  28. <!-- 配置日志记录最终通知 -->
  29. <aop:after method="after" pointcut-ref="p1"/>
  30. <!-- 配置日志记录环绕通知 -->
  31. <aop:around method="aroundTest" pointcut-ref="p1"/>
  32. </aop:aspect>
  33. </aop:config>
  34. </beans>


Exception in thread "main" java.lang.ClassCastException: com.bean.PhoneBizImpl

EnhancerByCGLIB E n h a n c e r B y C G L I B

 

at com.test.Test.main(Test.java:23)

 

直接使用代理类而不是代理接口的原因。在配置文件中加proxy-target-class="true"即可。

使用System.out.println(phoneBiz.getClass().getName());输出类的名称,出来的是$Proxy4,说明我们获得不是一个接口实现类的对象,而是一个代理对象,而且该代理对象实现了PhoneBiz接口,因此,你不能使用PhoneBizImpl来强转act.getBean("phoneBiz")

 

文章来源: aaaedu.blog.csdn.net,作者:tea_year,版权归原作者所有,如需转载,请联系作者。

原文链接:aaaedu.blog.csdn.net/article/details/53929069

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。