一、引言
在本章中我明白了spring框架中的代理的形成;
二、Aop代理
对于一个既定类,其方法中的代码很有可能能会出现大规模的重复,但是这些重复我们又可以找出一定的方法通过一个可以为其归类,这是我们就用到了spring代理的办法->这样可以使代码方法只写代码的关键点,而不重要的地方我们可以通过代理的方式实现代码的复用
三、操作流程
(1)jar 文件:
(2)spring文件中的配置
<context:component-scan base-package="club.shaoyu"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy><!-- 是指代理-->
(3)声明代理
@Aspect
@Component
public class aop {
}
注:Aop 代理类需要在类上添加@Aspect声明
(4)代理方法分类
方式:添加注解,并在注解上添加相应的注释
注释类型:@Before @After @AfterReturning @AfterThrowing @Around
注释属性:value=“execution(访问权限 返回值 类所在的路径 . 类名(*为全选)(..))”
(5)使用方法:
@Before :
在方法作用之前:
@Before("execution(public int club.shaoyu.computer.service.ComputerService.*(..))")
public void before(JoinPoint jp) {
Object[] args=jp.getArgs();
Signature s=jp.getSignature();
String name=s.getName();
System.out.println(this.getClass().getName()+":The "+name+" method begins.");
System.out.println(this.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
注释说明:其中的jp 为传参,而其中的getArgs()返回的是Object[] 数组,其对应的是传入的参数
execution 后面的是定位的类所在,本次的解释是:在:类ComputerService中的全部public int 的方法创建代理
在执行代理类中的方法前先执行before方法中的代码
@After
@After("execution(public int club.shaoyu.computer.service.ComputerService.*(..))")
public void after(JoinPoint jp) {
Signature s=jp.getSignature();
String name=s.getName();
System.out.println(this.getClass().getName()+":The "+name+" method ends.");
}
注释说明:getSignature()方法获得储存有Classname的signature对象
@AfterReturning
@AfterReturning(value="execution(public int club.shaoyu.computer.service.ComputerService.*(..))",returning="result")
public void after(JoinPoint jp,Object result) {
Signature s=jp.getSignature();
String name=s.getName();
System.out.println(this.getClass().getName()+":Result of the "+name+" method:"+result);
}
注释:此时输入两个参数,即将参数分为value 和result ,其中reusult代表被代理方法执行的结果为多少
@AfterThrowing
@AfterThrowing(value="execution(public int club.shaoyu.computer.service.ComputerService.*(..))",throwing="e")
public void afterThrowing(JoinPoint jp, Exception e) {
System.out.println(e.getMessage());
}
当执行方法中出现异常时,我们可以对该异常进行代理
@Around
可以在@Around中执行执行以上全部代理方法:
@Around(value="execution(public int club.shaoyu.computer.service.ComputerService.*(..))")
public Object around(ProceedingJoinPoint pjp) {
Object [] args=pjp.getArgs();
Object result=null;
Signature signature=pjp.getSignature();
String name=signature.getName();
System.out.println(this.getClass().getName()+":The "+name+" method begins.");
System.out.println(this.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
try {
try {
System.out.println(pjp.getTarget());
result=pjp.proceed();
}finally{
System.out.println(this.getClass().getName()+":The "+name+" method ends.");
}
System.out.println(this.getClass().getName()+":Result of the "+name+" method:"+result);
return result;
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return -1;
}
}
注:此时的执行传参已经改变: ProceedingJoinPoint类型
该代理的执行方式有所不同,因为要区分如何才可以是执行前,采用pjp.proceed()方法,其前面为before内容,其后是异常处理等操作
(5)Aop:
只需要将类的方法的核心写入代码中,前后不必要的说明可以使用代理的方法进行简化,是一个十分方便的方式
测试的话,创建以上结构的类,在测试类中测试