文章目录
1.基本介绍
1.什么是AOP?
2.示意图
3.五种通知
2.AOP快速入门
1.入门案例
1.导入jar包
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);
}
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 {
@Override
public double getSub(double num1, double num2) {
System.out.println("方法内部打印:" + (num1 - num2));
return num1 - num2;
}
@Override
public double getSum(double num1, double num2) {
System.out.println("方法内部打印:" + (num1 + num2));
return num1 + num2;
}
}
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
<?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);
}
}
2.细节说明
3.AOP理解(重点)
1.使用场景
需要对接口对象/普通对象的方法进行额外的操作而不想修改源代码时使用
2.代理对象理解
从接口类型或者接口对象id获取的bean对象的运行类型都是代理对象,编译类型是接口类型,最终执行方法的对象是代理对象
一个代理对象对应一个接口对象,在只有一个接口对象的时候才能使用类型来获取
3.AOP的实现方式
- 编写接口
- 编写实现类,使用注解自动创建bean对象
- 编写切面类,使用注解
- 自动创建bean对象
- 标识切面类
- 通知 + 切入表达式(切点)
- 编写xml文件
- 扫描普通注解
- 开启aop注解功能
- 使用方式
- 使用id或者类型获取针对接口的代理对象
- 使用代理对象执行方法
4.简化的AOP实现方式
- 接口,接口对象(注解)
- 切面(注解),切面对象(注解)
- 通知 + 切点
- 使用方式
- 使用id或者类型获取针对接口的代理对象
- 使用代理对象执行方法
4.课后练习
1.题目
2.答案
1.UsbInterface.java
java
package com.sxs.spring.aop.homework01;
/**
* @author 孙显圣
* @version 1.0
*/
public interface UsbInterface {
public void work();
}
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{
@Override
public void work() {
System.out.println("相机正在工作。。。。。。");
}
}
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{
@Override
public void work() {
System.out.println("手机正在工作。。。。。。");
}
}
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
<?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();
}
}
3.切入表达式
1.基本介绍
2.举例说明
3.注意事项和细节(重点)
1.切入表达式格式
java
*(访问修饰符(空格)返回类型)(空格)*(全类名/接口名/简单类名/简单接口名).*(方法名)(..)(参数类型)
简称: 星 星点星(点点)
注意:
- 访问修饰符和返回类型可以使用单个*****来表示任意的,必须满足中间有空格,比如 public * ...
- 使用简单类名/简单接口名则必须与切面类在同一个包下
- 如果配置了接口类型,则包括接口对象的所有方法
2.细节
3.Proxy和CGlib的区别
- Proxy是针对接口的代理对象,可以执行接口的所有方法
- CGlib是针对父类的代理对象,可以执行该类的所有法
4.JoinPoint常用方法
1.基本介绍
2.代码实例(使用普通对象)
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在运行!");
}
}
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
<?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.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.返回通知获取结果
代码实例
修改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);
}
}
6.异常通知获取异常
代码实例
1.修改Car.java
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);
}
7.环绕通知
代码实例
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!";
}
}
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
<?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>
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("小白");
}
}
8.切入表达式重用
代码实例
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在运行!");
}
}
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
<?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();
}
}
9.AOP多切面优先级问题
解释
- 多个切面同时切一个方法
- 可以给切面类配置Order注解,数值越小,前置通知先执行
- 执行完前置通知之后执行目标方法
- 然后按照相反的顺序执行多个切面的返回通知、异常通知、最终通知
10.根据xml配置AOP
代码实例
1.UsbInterface.java
java
package com.sxs.spring.aop.xml;
/**
* @author 孙显圣
* @version 1.0
*/
public interface UsbInterface {
public void work();
}
2.Camera.java
java
package com.sxs.spring.aop.xml;
/**
* @author 孙显圣
* @version 1.0
*/
public class Camera implements UsbInterface {
@Override
public void work() {
System.out.println("相机正在工作。。。。。。");
}
}
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
<?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();
}
}
11.课后练习
1.注解实现
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);
}
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
*/
@Override
public 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
*/
@Override
public void cal2(int n) {
int accumulate = 1;
for (int i = 1; i <= n; i++) {
accumulate *= i;
}
System.out.println("1到n的积=" + accumulate);
}
}
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);
}
}
2.xml实现
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);
}
2.CalImpl.java
java
package com.sxs.spring.aop.homework03;
/**
* @author 孙显圣
* @version 1.0
*/
public class CalImpl implements Cal {
/**
* 计算1到n的和
* @param n
*/
@Override
public 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
*/
@Override
public void cal2(int n) {
int accumulate = 1;
for (int i = 1; i <= n; i++) {
accumulate *= i;
}
System.out.println("1到n的积=" + accumulate);
}
}
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
<?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);
}
}