一、代理目标(target)
谁将被其他对象代理,谁就是代理目标
二、代理对象(proxy)
谁将代理其他对象,谁就是代理对象
三、连接点(Join Point)
1.执行点
任意一个可以执行的方法都可以当作一个执行点
2.方位
方法执行前(before)
方法执行前后(around)
方法抛出异常后(after-throw)
方法正常返回后(after-return)
方法执行后(after)
3.连接点
连接点=执行点+方位
四、切点(Pointcut)
对连接点进行筛选的条件
要指定执行点和方位信息
确定在哪加入代码
五、Advice
在指定的切点所选择的连接点加入的代码就是Advice
确定加入什么代码
六、切面(Aspect)
切面(Aapect)=切点(Pointcut)+Advice
在哪里加,加什么代码(在哪里加什么)
示例代码:
第一步:创建Cat.java和CatAdvices.java类
Cat.java类:
public class Cat { private String name; public void eat(String food){ System.out.println(this.name+"吃"+food); } public int div(int a,int b){ int c=a/b; return c; }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
CatAdvices.java类:
public class CatAdvices { public void before(JoinPoint joinPoint){ Signature signature=joinPoint.getSignature();// 获取 连接点 对应的 方法 的 签名 System.out.println("signature"+signature); int mod=signature.getModifiers();// 获得方法的 修饰符 ( 以整数形式返回 ) String modifier= Modifier.toString(mod);// 将 整数形式表示的 修饰符 解析为 字符串 形式 System.out.println("modifier"+modifier); String modName=signature.getName(); // 获取 方法名称 System.out.println("modName"+modName); Object[] args=joinPoint.getArgs(); System.out.println("arguments"+Arrays.toString(args)); System.out.println("【"+modName+"】方法即将执行!"); } public Object round(ProceedingJoinPoint joinPoint) throws Throwable{ String name=joinPoint.getSignature().getName(); System.out.println("开始为"+name+"计时"); long begin=System.nanoTime(); Object result=joinPoint.proceed(); long end=System.nanoTime(); System.out.println("为"+name+"计时结束"); System.out.println("["+name+"耗时"+(end-begin)+"ns]"); return result;// 返回 由 被拦截的方法执行后 所返回的值 }
public void afterReturn(JoinPoint joinPoint,Object xxx){
System.out.println("【"+joinPoint.getSignature().getName()+"】方法执行后返回了"+"【"+xxx+"】");
}
public void afterThrow(JoinPoint joinPoint,Throwable ex){
System.out.println("【"+joinPoint.getSignature().getName()+"】方法执行时抛出了"+ex);
}
public void after(JoinPoint joinPoint){
// 获取 连接点 对应的 方法 的 签名
Signature signature=joinPoint.getSignature();
String mothodName=signature.getName();
System.out.println("【"+mothodName+"】执行结束!");
}
}
第二步:
aop-schema.xml
<!-- 确定需要 添加的代码所在的 bean --> <bean id="catAdvices" class="com.itlaobing.aop.schema.CatAdvices"/> <!-- 确定代理目标(谁将被代理) --> <bean id="cat" class="com.itlaobing.aop.schema.Cat" p:name="琪琪"/> <!--提供AOP的配置--> aop:config <aop:aspect ref="catAdvices"> <aop:pointcut id="pc" expression="execution(* com..schema.Cat.*(..))"/> <aop:before method="before" pointcut-ref="pc"/> <aop:after method="after" pointcut-ref="pc"/> <aop:after-returning method="afterReturn" pointcut-ref="pc" returning="xxx"/> <aop:after-throwing method="afterThrow" pointcut-ref="pc" throwing="ex"/> <aop:around method="round" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans>
第三步
public class CatTest1 { public static void main(String[] args) { String configLocation="com/itlaobing/aop/schema/aop-schema. AbstractApplicationContext container=new ClassPathXmlApplicationContext(configLocation); Object proxy=container.getBean("cat"); System.out.println(proxy.getClass().getName()); Class<?> clazz=proxy.getClass().getSuperclass(); System.out.println(clazz); if(proxy instanceof Cat){ Cat cat=(Cat)proxy; cat.eat("鱼"); System.out.println("---------------------1-----------------------"); String catName= cat.getName(); System.out.println(catName); System.out.println("---------------------2-----------------------"); int result=cat.div(100,2); System.out.println(result); System.out.println("---------------------3-----------------------"); result=cat.div(100,0); System.out.println(result); } container.close();
}
}