基于XML的声明式AspectJ

基于xml的AspectJ:一个AOP框架:通过xml文件配置:通过aop:config元素定义切面点,通知等。
常用元素与子元素嵌套关系:

aop:config的子元素:aop:aspect
aop:aspect的子元素:(id:唯一标识,ref:引用普通的spring bean)
1.aop:pointcut(配置全局切入点):(id:唯一标识,expression:写切入点表达式)
2.aop:before(配置前置通知)(method:想要增强的方法,pointcut-ref:把配置的切入点的id写进来)
3.aop:after-returning(配置后置通知)(method:同上,pointcut-ref:同上,returning:通过该形参访问目标方法返回值)
4.aop:around(配置环绕通知)(method:同上,pointcut-ref:同上)
5.aop:after-throwing(配置异常通知)(method:同上,pointcut-ref:同上,throwing:通过该形参访问方法返回值)
6.aop:after(配置最终通知)(method:同上,pointcut-ref:同上)


结构:
aop:config
aop:aspect(配置切面)

<aop:pointcut />(配置全局切入点)
<aop:befor />
<aop:after-returning />
<aop:around />
<aop:after-throwing />
<aop:after />

</aop:aspect>
</aop:config>


例如:


切入点:通俗易懂的说,你想在哪个方法的前或者后增加通知/增强处理。那个位置(那个方法)就是切入点,你在那个切入点前添加了通知,就是前置通知。你在那个切入点后添加通知,就是后置通知。
切入点表达式:execution表达式:
访问修饰符 返回值类型 类路径 目标方法 参数 异常类型(加粗为必须值)
例如:public void com.meicong.jdk.UserDaoImpl.adduser()(…)
访问修饰符的位置填写一个 *,代表随意,任意都可以。


//定义切面类
public class MyAspect {
    
//前置通知:
public void myBefore(JoinPoint joinPoint) {
          //用JoinPoint接口作为参数获取目标对象的信息,方法,类名等。(记住这么写,获取信息用) 
System.out.print(" 前置通知:模拟执行权限检查. . . , " ) ;   
System.out.print(" 目标类是: "+joinPoint.getTarget() );    //joinPoint.getTarget:目标类,也就是要增加通知的那个目标类。Target:目标。
System.out.println(" ,被织入增强处理的目标方法为: " +joinPoint.getSignature().getName()) ;  //获取目标方法。 
}
//后置通知:
public void myAfterReturning(JoinPoint joinPoint) {
    
System.out.print(" 后置通知:模拟记录日志. . . ," ); 
System.out.println(" 被植入增强处理的目标方法为: " + joinPoint.getSignature() .getName()); 
}
//环绕通知:前和后都有,返回值为Object,参数这里有改变,这是JoinPoint的子接口,必须有异常处理。
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) 
throws Throwable {
    
System.out.println("环绕开始:执行目标方法之前,模拟开启事务. . . ") ; 
Object obj = proceedingJoinPoint.proceed() ;     //执行当前目标方法,也就是你准备要添加通知的那个方法,他的前后都加了通知。
System out println("环绕结束 执行门标方法之后 模拟关闭事务 . . ") ; 
return obj;     //返回obj
}
//异常通知:出现异常时的通知
public void myAfterThrowing(JoinPoint joinPoint, Throwable e ) {
    
System out println("异常通知:"+"出错了" + e.getMessage()); 
}
//最终通知:最后一定会执行的通知
public void myAfter() {
    
System out println("最终通知 模拟方法结束后的释放资源 . . ") ; 
}
}
//xml配置文件主要代码:

<bean id="userDao" class=" com.itheima.jdk.UserDaolmpl" />    //配置目标类
<bean id="myAspect" class="com.itheima.aspectj.xml.MyAspect" />   //配置切面类
<aop:config>
<aop:aspect ref="myAspect " >     //配置切面,ref指向的就是切面类的id 
<aop:pointcut expression="execution(* com.itheima.jdk.*.*(..))"   //配置切入点,就是要增强什么方法,用切入点表达式 
id="myPointCut" /> 
<aop:before method="myBefore" pointcut-ref="myPointCut" />      //前置,对用的那个前置方法,把这个前置方法加入到目标对象上。 
<aop:after-returning method="myAfterReturning"             //指向切入点。
pointcut-ref="myPointCut" returning="returnVal" />         //同理 后置通知可返回方法返回值,returning。
<aop:around method="myAround" pointcut-ref="myPointCut" /> 
<aop:after-throwing method="myAfterThrowing" 
pointcut-ref="PointCut" throwing="e" />    //异常处理
<aop:after method="myAfter" pointcut-ref="myPointCut" />
</aop:aspect>
</aop:config> 
</beans>

public class TestXmlAspectj {
   
public static void main(String args[)) {
   
String xmlPath =
"com/itheima/aspectj/xml/applicationContext . xml"; 
ApplicationContext applicationContext = 
new ClassPath nlApplicationContext(xmlPath);
UserDao userDao = (UserDao) applicationContext.getBean("userDao"); 
userDao.addUser();
}
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务