AspectJ中的实现
在spring中的基本实现步骤
- 创建配置文件:声明对象,把对象交给容器同一管理,可以用<bean>或注解
1)声明目标对象
2)声明给你切面类对象
3)声明aspectj框架中的自动代理生成器标签。
自动代理生成器:用于完成代理对象的自动创建功能的。
第一步:添加aspectj依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
第二步:创建目标类
创建接口和他的实现类(要做的是给类中的方法增加功能)这里仍然用Hello来模仿子
package org.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Hello implements HelloInterface {
@Value("yasuo")
private String name;
public void sayHello(String name){
System.out.println(name+":pasaki");
}
}
现在要在执行目标类之前打印系统时间
第三步:创建切面类:普通类
1)在类上面加入@Aspect
2)在类中定义方法,方法就是切面。
3)执行要的功能代码在方法上面加入的AspectJ中的通知注解例如@Before有需要指定切入点表达式执行()
package org.example;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
@Aspect
public class MyAspect {
/*
定义方法实现切面功能:
1.公共方法
2.方法没有返回值
3.方法名称自定义
4.方法可以有参数,也可以没有参数
如果有参数,参数不是自定义的,有几个参数类型可以使用
*/
//value是切入点表达式,表示切面的功能执行的位置
@Before("execution(public void org.example.Hello.sayHello(String))")
public void myBefore(){
//功能代码
System.out.println("切面功能,执行之前"+new Date());
}
}
第四步:创建配置文件
在spring配置文件中配置相关内容
声明对象,把对象交给容器同一管理,可以用<bean>或注解
1)声明目标对象
2)声明给你切面类对象
3)声明aspectj框架中的自动代理生成器标签。
自动代理生成器:用于完成代理对象的自动创建功能的。
<?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="org.example"/>
<!-- 声明自动代理生成器:使用aspectj框架内部的功能,创建目标对象的代理对象。
创建代理对象是在内存中实现的,修改目标对象的内存中的结构。创建为代理对象所以目标对象
就是被修改后的代理对象-->
<!-- aspctj-autoproxy:会把spring容器中的所有目标对象,一次性都生成代理对象-->
<aop:aspectj-autoproxy/>
</beans>
测试
//1、指定spring配置文件的名称
String config="spring_total" + ".xml";
//2、创建表示spring容器的对象,ApplicationContext
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
//3、通过容器获取对象
HelloInterface hello = (HelloInterface) context.getBean("hello");
hello.sayHello("yasuo");
JoinPoint
指定通知方法中的参数:JoinPoint
作用是:可以在通知方法中获取方法执行时信息,例如方法名称,方法的实参
如果切面功能中需要用到方法的信息,就加入JoinPoint
这个JoinPoint参数的值是由框架赋予,必须是第一个位置的参数
@Before("execution(public void org.example.Hello.sayHello(String))")
public void myBefore(JoinPoint joinPoint){
//获取方法完整的定义
System.out.println("方法的签名(定义)="+joinPoint.getSignature());
System.out.println("方法的名称="+joinPoint.getSignature().getName());
//获取方法实参
Object[] args = joinPoint.getArgs();
for(Object arg:args){
System.out.println("参数="+arg);
}
//功能代码
System.out.println("切面功能,执行之前"+new Date());
}