Spring-AOP

server/2024/10/18 18:15:22/

文章目录

    • 1.基本介绍
        • 1.什么是AOP?
        • 2.示意图
        • 3.五种通知
    • 2.AOP快速入门
        • 1.入门案例
          • 1.导入jar包
          • 2.Cal.java 接口
          • 3.CalImpl.java 实现类
          • 4.CalAspect.java 切面类
          • 5.beans06.xml 开启注解功能
          • 6.测试
        • 2.细节说明
        • 3.AOP理解(重点)
          • 1.使用场景
          • 2.代理对象理解
          • 3.AOP的实现方式
        • 4.简化的AOP实现方式
        • 4.课后练习
          • 1.题目
          • 2.答案
    • 3.切入表达式
        • 1.基本介绍
        • 2.举例说明
        • 3.注意事项和细节(重点)
          • 1.切入表达式格式
            • **注意:**
          • 2.细节
          • 3.Proxy和CGlib的区别
    • 4.JoinPoint常用方法
        • 1.基本介绍
        • 2.代码实例(使用普通对象)
    • 5.返回通知获取结果
        • 代码实例
    • 6.异常通知获取异常
        • 代码实例
    • 7.环绕通知
        • 代码实例
    • 8.切入表达式重用
        • 代码实例
          • 1.Car.java
          • 2.Aspect02.java
          • 3.beans06.xml
          • 4.测试
    • 9.AOP多切面优先级问题
          • 解释
    • 10.根据xml配置AOP
        • 代码实例
          • 1.UsbInterface.java
          • 2.Camera.java
          • 3.Aspect.java
          • 4.beans07.xml
          • 5.测试
    • 11.课后练习
        • 1.注解实现
          • 1.Cal.java
          • 2.CalImpl.java
          • 3.Aspect_ann.java
          • 4.beans06.xml
          • 5.测试
        • 2.xml实现
          • 1.Cal.java
          • 2.CalImpl.java
          • 3.Aspect_xml.java
          • 4.beans08.xml
          • 5.测试

1.基本介绍

1.什么是AOP?

image-20240220103241229

2.示意图

image-20240220105205993

image-20240220105239393

3.五种通知

image-20240220110125266

image-20240220110136565

2.AOP快速入门

1.入门案例
1.导入jar包

image-20240220110639212

java__28">2.Cal.java 接口
java">package com.sxs.spring.aop.aspectj;/*** 计算数量的接口** @author 孙显圣* @version 1.0*/
public interface Cal {public double getSub(double num1, double num2);public double getSum(double num1, double num2);
}
java__46">3.CalImpl.java 实现类
java">package com.sxs.spring.aop.aspectj;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/@Component //注解创建bean对象
public class CalImpl implements Cal {@Overridepublic double getSub(double num1, double num2) {System.out.println("方法内部打印:" + (num1 - num2));return num1 - num2;}@Overridepublic double getSum(double num1, double num2) {System.out.println("方法内部打印:" + (num1 + num2));return num1 + num2;}
}
java__75">4.CalAspect.java 切面类
java">package com.sxs.spring.aop.aspectj;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.Arrays;/*** 切面类** @author 孙显圣* @version 1.0*/
@Component //自动创建bean对象
@Aspect //切面类
public class CalAspect {/*** @param joinPoint 保存了要切入的方法的信息* @Before 前置通知* execution(。。。) 切入表达式,表明要切入的方法,格式:格式:访问修饰符+返回类型 全类名 方法名(参数类型)*/@Before(value = "execution(public double com.sxs.spring.aop.aspectj.CalImpl.getSub(double, double))")public void before(JoinPoint joinPoint) {//获取方法签名Signature signature = joinPoint.getSignature();System.out.println("方法执行开始-日志-方法名-" + signature.getName()+ "-参数" + Arrays.asList(joinPoint.getArgs()));}/*** @param joinPoint 保存了要切入的方法的信息* @AfterReturning 返回通知*/@AfterReturning(value = "execution(public double com.sxs.spring.aop.aspectj.CalImpl.getSub(double, double))")public void afterReturning(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法执行正常结束-日志-方法名-" + signature.getName());}/*** @param joinPoint* @AfterThrowing 异常通知*/@AfterThrowing(value = "execution(public double com.sxs.spring.aop.aspectj.CalImpl.getSub(double, double))")public void throwing(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法出现异常-日志-方法名-" + signature.getName());}/*** @param joinPoint* @After 后置通知*/@After(value = "execution(public double com.sxs.spring.aop.aspectj.CalImpl.getSub(double, double))")public void after(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法最终执行完毕-日志-方法名-" + signature.getName());}
}
5.beans06.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.aspectj"/>
<!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
6.测试
java">package com.sxs.spring.aop.aspectj;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class AopAspectjTest {public static void main(String[] args) {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");//注意:这里需要使用接口类型来获取代理对象,然后使用代理对象来执行方法,才能实现切面编程Cal bean = ioc.getBean(Cal.class);bean.getSub(1,22);}
}

image-20240220144144990

2.细节说明

image-20240220145619074

3.AOP理解(重点)
1.使用场景

需要对接口对象/普通对象的方法进行额外的操作而不想修改源代码时使用

2.代理对象理解

从接口类型或者接口对象id获取的bean对象的运行类型都是代理对象,编译类型是接口类型,最终执行方法的对象是代理对象

一个代理对象对应一个接口对象,在只有一个接口对象的时候才能使用类型来获取

3.AOP的实现方式
  1. 编写接口
  2. 编写实现类,使用注解自动创建bean对象
  3. 编写切面类,使用注解
    1. 自动创建bean对象
    2. 标识切面类
    3. 通知 + 切入表达式(切点)
  4. 编写xml文件
    1. 扫描普通注解
    2. 开启aop注解功能
  5. 使用方式
    1. 使用id或者类型获取针对接口的代理对象
    2. 使用代理对象执行方法
4.简化的AOP实现方式
  1. 接口,接口对象(注解)
  2. 切面(注解),切面对象(注解)
  3. 通知 + 切点
  4. 使用方式
    1. 使用id或者类型获取针对接口的代理对象
    2. 使用代理对象执行方法
4.课后练习
1.题目

image-20240220150422379

2.答案
java_235">1.UsbInterface.java
java">package com.sxs.spring.aop.homework01;/*** @author 孙显圣* @version 1.0*/
public interface UsbInterface {public void work();
}
java_250">2.Camera.java
java">package com.sxs.spring.aop.homework01;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class Camera implements UsbInterface{@Overridepublic void work() {System.out.println("相机正在工作。。。。。。");}
}
java_271">3.Phone.java
java">package com.sxs.spring.aop.homework01;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class Phone implements UsbInterface{@Overridepublic void work() {System.out.println("手机正在工作。。。。。。");}
}
java_292">4.Aspect.java
java">package com.sxs.spring.aop.homework01;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect {@Before(value = "execution(* com.sxs.spring.aop.homework01.*.*(..))")public void before(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("日志-方法执行前-方法名-" + signature.getName());}
}
5.beans06.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.homework01"/>
<!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
6.测试
java">package com.sxs.spring.aop.homework01;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class test {public static void main(String[] args) {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");//通过id获取代理对象UsbInterface bean1 = (UsbInterface) ioc.getBean("camera");//执行方法bean1.work();//通过id获取代理对象UsbInterface bean2 = (UsbInterface) ioc.getBean("phone");//执行方法bean2.work();}
}

image-20240220154136556

3.切入表达式

1.基本介绍

image-20240220154944257

2.举例说明

image-20240220155134259

image-20240220155150216

3.注意事项和细节(重点)
1.切入表达式格式
java">*(访问修饰符(空格)返回类型)(空格)*(全类名/接口名/简单类名/简单接口名).*(方法名)(..)(参数类型)
简称: 星 星点星(点点)    
注意:
  • 访问修饰符和返回类型可以使用单个*****来表示任意的,必须满足中间有空格,比如 public * …
  • 使用简单类名/简单接口名则必须与切面类在同一个包下
  • 如果配置了接口类型,则包括接口对象的所有方法
2.细节

image-20240220161248432

3.Proxy和CGlib的区别
  • Proxy是针对接口的代理对象,可以执行接口的所有方法
  • CGlib是针对父类的代理对象,可以执行该类的所有法

4.JoinPoint常用方法

1.基本介绍

image-20240220162304414

2.代码实例(使用普通对象)
java_408">1.Car.java
java">package com.sxs.spring.aop.joinpoint;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class Car {public void run() {System.out.println("Car在运行!");}
}
java_428">2.Aspect02.java
java">package com.sxs.spring.aop.joinpoint;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect02 {//返回通知@AfterReturning(value = "execution(* Car.run())")public void afterReturning(JoinPoint joinPoint) {System.out.println("方法执行完毕!");Signature signature = joinPoint.getSignature();System.out.println("name=" + signature.getName());System.out.println("simpleName=" + signature.getDeclaringType().getSimpleName());System.out.println("该方法所属类的类名=" + signature.getDeclaringTypeName());System.out.println("参数=" + joinPoint.getArgs());}
}
3.beans06.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.joinpoint"/>
<!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
java_475">4.test.java
java">package com.sxs.spring.aop.joinpoint;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class test {public static void main(String[] args) {//获取针对父类的代理对象ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");Car bean = ioc.getBean(Car.class);bean.run();}
}

5.返回通知获取结果

代码实例
java_502">修改Aspect02.java
java">package com.sxs.spring.aop.joinpoint;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect02 {/*** 返回通知获取结果** @param joinPoint* @param res 参数名必须与returning的一致*/@AfterReturning(value = "execution(* Car.run())", returning = "res")public void afterReturning(JoinPoint joinPoint, Object res) {System.out.println("返回结果为=" + res);}
}

image-20240220170459897

6.异常通知获取异常

代码实例
java_539">1.修改Car.java

image-20240220172325445

java_543">2.修改Aspect02.java
java">    /*** 异常通知获取异常** @param joinPoint* @param throwable 参数名必须与throwing一致*/@AfterThrowing(value = "execution(* Car.run())", throwing = "throwable")public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {System.out.println("异常通知获取异常:" + throwable);}

image-20240220172407848

7.环绕通知

代码实例
java_564">1.Dog.java
java">package com.sxs.spring.aop.doArround;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class Dog {public String sayHi(String name) {System.out.println(name + "wang,wang!");return name + "wang,wang!";}
}
java_586">2.Aspect03.java
java">package com.sxs.spring.aop.doArround;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;import java.util.Arrays;
import java.util.List;/*** 环绕通知** @author 孙显圣* @version 1.0*/
@Component
@Aspect
public class Aspect03 {/*** @param joinPoint 连接点对象* @return 返回结果*/@Around(value = "execution(public String sayHi(String))")public Object doArround(ProceedingJoinPoint joinPoint) {Object result = null;String methodName = joinPoint.getSignature().getName();try {Object[] args = joinPoint.getArgs();List<Object> list = Arrays.asList(args);//1.前置通知System.out.println("AOP环绕通知-前置通知-方法名=" + methodName + "-参数-" + list);//执行方法result = joinPoint.proceed();//2.返回通知System.out.println("AOP环绕通知-返回通知-方法名=" + methodName + "-结果为=" + result);} catch (Throwable e) {//3.异常通知System.out.println("AOP环绕通知-异常通知-方法名=" + methodName + "-异常=" + e);} finally {//4.后置通知System.out.println("AOP环绕通知-后置通知-方法名=" + methodName);}return result;}
}
3.beans06.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.doArround"/>
<!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
java_654">4.Test.java
java">package com.sxs.spring.aop.doArround;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class Test {public static void main(String[] args) {//读取配置文件获取容器ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");//获取针对父类的代理对象Dog bean = ioc.getBean(Dog.class);//执行方法bean.sayHi("小白");}
}

image-20240220184215190

8.切入表达式重用

代码实例
java_685">1.Car.java
java">package com.sxs.spring.aop.joinpoint;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class Car {public void run() {System.out.println("Car在运行!");}
}
java_705">2.Aspect02.java
java">package com.sxs.spring.aop.joinpoint;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect02 {//定义切点函数,实现切入表达式重用@Pointcut(value = "execution(* Car.run())") //设置切入表达式public void pointCut() {}/*** 前置通知** @param joinPoint*/@Before(value = "pointCut()")public void before(JoinPoint joinPoint) {System.out.println("前置通知");}/*** 返回通知获取结果** @param joinPoint* @param res       参数名必须与returning的一致*/@AfterReturning(value = "pointCut()", returning = "res")public void afterReturning(JoinPoint joinPoint, Object res) {System.out.println("返回结果为=" + res);}/*** 异常通知获取异常** @param joinPoint* @param throwable 参数名必须与throwing一致*/@AfterThrowing(value = "pointCut()", throwing = "throwable")public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {System.out.println("异常通知获取异常:" + throwable);}/*** 后置通知* @param joinPoint*/@After(value = "pointCut()")public void after(JoinPoint joinPoint) {System.out.println("后置通知");}
}
3.beans06.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.joinpoint"/>
<!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
4.测试
java">package com.sxs.spring.aop.joinpoint;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class test {public static void main(String[] args) {//获取针对父类的代理对象ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");Car bean = ioc.getBean(Car.class);bean.run();}
}

image-20240220185731772

9.AOP多切面优先级问题

image-20240220190818126

解释
  1. 多个切面同时切一个方法
  2. 可以给切面类配置Order注解,数值越小,前置通知先执行
  3. 执行完前置通知之后执行目标方法
  4. 然后按照相反的顺序执行多个切面的返回通知、异常通知、最终通知

10.根据xml配置AOP

代码实例
java_828">1.UsbInterface.java
java">package com.sxs.spring.aop.xml;/*** @author 孙显圣* @version 1.0*/
public interface UsbInterface {public void work();
}
java_843">2.Camera.java
java">package com.sxs.spring.aop.xml;/*** @author 孙显圣* @version 1.0*/
public class Camera implements UsbInterface {@Overridepublic void work() {System.out.println("相机正在工作。。。。。。");}
}
java_862">3.Aspect.java
java">package com.sxs.spring.aop.xml;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** @author 孙显圣* @version 1.0*/
public class Aspect {/*** @param joinPoint 保存了要切入的方法的信息* @Before 前置通知* execution(。。。) 切入表达式,表明要切入的方法,格式:访问修饰符+返回类型 全类名 方法名(参数类型)*/public void before(JoinPoint joinPoint) {//获取方法签名Signature signature = joinPoint.getSignature();System.out.println("方法执行开始-日志-方法名-" + signature.getName()+ "-参数" + Arrays.asList(joinPoint.getArgs()));}/*** @param joinPoint 保存了要切入的方法的信息* @AfterReturning 返回通知*/public void afterReturning(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("方法执行正常结束-日志-方法名-" + signature.getName());}/*** @param joinPoint* @AfterThrowing 异常通知*/public void throwing(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("方法出现异常-日志-方法名-" + signature.getName());}/*** @param joinPoint* @After 后置通知*/public void after(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法最终执行完毕-日志-方法名-" + signature.getName());}}
4.beans07.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.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--创建被切入的接口对象--><bean class="com.sxs.spring.aop.xml.Camera" id="camera"/><!--配置切面对象--><bean class="com.sxs.spring.aop.xml.Aspect" id="aspect"/><!--配置AOP--><aop:config><!--配置切点--><aop:pointcut id="poingCut" expression="execution(public void work())"/><!--配置切面--><aop:aspect ref="aspect" order="10"><!--前置通知--><aop:before method="before" pointcut-ref="poingCut"/><!--返回通知--><aop:after-returning method="afterReturning" pointcut-ref="poingCut" returning="res"/><!--异常通知--><aop:after-throwing method="throwing" pointcut-ref="poingCut" throwing="throwable"/><!--后置通知--><aop:after method="after" pointcut-ref="poingCut"/></aop:aspect></aop:config>
</beans>
5.测试
java">package com.sxs.spring.aop.xml;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class Test {public static void main(String[] args) {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans07.xml");//获得针对接口的代理对象UsbInterface bean = ioc.getBean(UsbInterface.class);bean.work();}
}

image-20240220195346934

11.课后练习

image-20240220202013336

1.注解实现
java_987">1.Cal.java
java">package com.sxs.spring.aop.homework02;/*** @author 孙显圣* @version 1.0*/
public interface Cal {public void cal1(int n);public void cal2(int n);
}
java_1003">2.CalImpl.java
java">package com.sxs.spring.aop.homework02;import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
public class CalImpl implements Cal{/*** 计算1到n的和* @param n*/@Overridepublic void cal1(int n) {int sum = 0;for (int i = 1; i <= n; i++) {sum += i;}System.out.println("1到n的和=" + sum);}/*** 计算1乘到n* @param n*/@Overridepublic void cal2(int n) {int accumulate = 1;for (int i = 1; i <= n; i++) {accumulate *= i;}System.out.println("1到n的积=" + accumulate);}
}
java_1045">3.Aspect_ann.java
java">package com.sxs.spring.aop.homework02;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;/*** @author 孙显圣* @version 1.0*/
@Component
@Aspect
public class Aspect_ann {//切入表达式重用@Pointcut(value = "execution(* CalImpl.*(..))")public void pointCut() {}//前置通知@Before(value = "pointCut()")public void before(JoinPoint joinPoint) {//获取目前的毫秒数long start = System.currentTimeMillis();//获取函数名String name = joinPoint.getSignature().getName();System.out.println(name + "开始时间=" + start);}//返回通知@AfterReturning(value = "pointCut()")public void afterReturning(JoinPoint joinPoint) {//获取目前的毫秒数long end = System.currentTimeMillis();//获取函数名String name = joinPoint.getSignature().getName();System.out.println(name + "结束=" + end);}
}
4.beans06.xml
java"><?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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--扫描普通注解--><context:component-scan base-package="com.sxs.spring.aop.homework02"/><!--开启基于aop的注解功能--><aop:aspectj-autoproxy/>
</beans>
5.测试
java">package com.sxs.spring.aop.homework02;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class Test_ann {public static void main(String[] args) {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");Cal bean = ioc.getBean(Cal.class);bean.cal1(5);System.out.println("===========================");bean.cal2(5);}
}

image-20240220202209913

2.xml实现
java_1139">1.Cal.java
java">package com.sxs.spring.aop.homework03;/*** @author 孙显圣* @version 1.0*/
public interface Cal {public void cal1(int n);public void cal2(int n);
}
java_1155">2.CalImpl.java
java">package com.sxs.spring.aop.homework03;/*** @author 孙显圣* @version 1.0*/
public class CalImpl implements Cal {/*** 计算1到n的和* @param n*/@Overridepublic void cal1(int n) {int sum = 0;for (int i = 1; i <= n; i++) {sum += i;}System.out.println("1到n的和=" + sum);}/*** 计算1乘到n* @param n*/@Overridepublic void cal2(int n) {int accumulate = 1;for (int i = 1; i <= n; i++) {accumulate *= i;}System.out.println("1到n的积=" + accumulate);}
}
java_1195">3.Aspect_xml.java
java">package com.sxs.spring.aop.homework03;import org.aspectj.lang.JoinPoint;/*** @author 孙显圣* @version 1.0*/
public class Aspect_xml {//前置通知public void before(JoinPoint joinPoint) {//获取目前的毫秒数long start = System.currentTimeMillis();//获取函数名String name = joinPoint.getSignature().getName();System.out.println(name + "开始时间=" + start);}//返回通知public void afterReturning(JoinPoint joinPoint) {//获取目前的毫秒数long end = System.currentTimeMillis();//获取函数名String name = joinPoint.getSignature().getName();System.out.println(name + "结束=" + end);}
}
4.beans08.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.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--反射创建实现类bean对象--><bean class="com.sxs.spring.aop.homework03.CalImpl" id="calImpl"/><!--反射创建切面类bean对象--><bean class="com.sxs.spring.aop.homework03.Aspect_xml" id="aspect_xml"/><!--配置aop--><aop:config><!--配置切点--><aop:pointcut id="pointCut" expression="execution(* com.sxs.spring.aop.homework03.CalImpl.*(..))"/><!--配置切面--><aop:aspect ref="aspect_xml" id="aspect" order="10"><aop:before method="before" pointcut-ref="pointCut"/><aop:after-returning method="afterReturning" pointcut-ref="pointCut"/></aop:aspect></aop:config>
</beans>
5.测试
java">package com.sxs.spring.aop.homework03;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 孙显圣* @version 1.0*/
public class Test_xml {public static void main(String[] args) {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans08.xml");//获取针对接口的代理对象Cal proxy = ioc.getBean("calImpl", Cal.class);proxy.cal1(100);System.out.println("=========================");proxy.cal2(5);}
}

image-20240220203820676


http://www.ppmy.cn/server/7466.html

相关文章

【Redis 神秘大陆】001 背景基础理论

一、背景&基础理论 1.1 什么是缓存 缓存&#xff1a;存储在计算机上的一个原始数据复制集&#xff0c;以便于访问——维基百科 1.2 为什么用缓存 提升用户体验&#xff1a; 【即效率、效益和基本主观满意度】CAST 使用者的状态、系统性能及环境&#xff0c;不同的人对于…

JAVA反射-loadClass和Class.forName的区别

类初始化的时机: ▲何时会触发类初始化? 对于第一次JVM执行&#xff0c;类初始化只执行1次&#xff01; 类会执行初始化。 通常来说&#xff0c;只要你使用该类&#xff0c;都属于主动使用类。但以下几种情况不属于主动使用: 1.使用类声明&#xff08;定义&#xff09;变量 2…

Git学习笔记(二)Git安装及基础命令

前面的文章中&#xff0c;我们已经对Git的一些基础知识进行了简单的介绍&#xff0c;包括它的作用&#xff0c;Git组件&#xff0c;文件状态以及一些简单的命令介绍等等。那么这一章主要介绍如何下载安装配置Git&#xff0c;以及Git的一些常用命令和实操截图。 Git下载与安装 …

javaWeb项目-大药房管理系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、Java语言简介 Ja…

供应链系统搭建|主流电商平台商品采集|一键搬家|订单物流回传API接口

搭建供应链系统时&#xff0c;您可能需要与电商平台进行集成&#xff0c;以实现订单管理、库存同步、物流跟踪等功能。以下是一些常见的电商接口&#xff0c;可以帮助您构建供应链系统&#xff1a; 1. **淘宝开放平台接口**&#xff1a;淘宝开放平台提供了丰富的接口&#xff…

Jmeter 接口造10w条用户数据

1、将mysql-connector-java-5.1.22-bin.jar放到D:\apache-jmeter-5.5\lib\ext目录下 2、在测试计划中&#xff0c;添加mysql-connector-java-5.1.22-bin.jar包路径 3、添加-线程组-添加-配置元件-jdbc connection configuration 4、配置jdbc连接参数 设置变量名称&#xff1a;…

【MySQL】20. 使用C语言链接

mysql connect mysql的基础&#xff0c;我们之前已经学过&#xff0c;后面我们只关心使用 要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作&#xff1a; …

idm线程越多越好吗 idm线程数多少合适

IDM&#xff08;Internet Download Manager&#xff09;是一款流行的下载管理软件&#xff0c;它支持多线程下载&#xff0c;这意味着它可以同时建立多个连接来下载文件的不同部分&#xff0c;从而提高下载速度。我们在使用IDM的时候总是有很多疑问&#xff0c;今天我们学习IDM…