国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php框架 > 框架设计 > Spring(十一)AspectJ框架开发AOP(基于xml)

Spring(十一)AspectJ框架开发AOP(基于xml)

来源:程序员人生   发布时间:2017-03-10 09:45:16 阅读次数:5625次

说明

AspectJ是1个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面,所以可使用xml方式和注解方式来开发AOP
新版本Spring框架,建议使用AspectJ方式来开发AOP
aspectj有5种通知

before( Formals )
前置通知(在方法履行前履行,如果通知抛出异常,禁止方法运行)
after( Formals ) returning [ ( Formal ) ]
后置通知(方法正常返回后履行,如果方法中抛出异常,通知没法履行
必须在方法履行后才履行,所以可以取得方法的返回值。)
after( Formals ) throwing [ ( Formal ) ]
异常停止(方法抛出异常后履行,如果方法没有抛出异常,没法履行)
after( Formals )
终究通知(方法履行终了后履行,不管方法中是不是出现异常,类似try-catch-finally里面的finally块)
around( Formals )
环绕通知( 方法履行前后分别履行,可以禁止方法的履行,必须手动履行目标方法)
在xml中对应:
这里写图片描述

导入的jar包:
1.aop同盟规范
2.spring aop实现
3.aspect规范
4.spring aspect实现
这里写图片描述

xml小例子

编写进程:
1.目标类:实现+接口
2.切面类:编写多个通知
3.aop编程,将通知利用到目标类
4.测试
目标类:
接口

public interface UserService {
    public boolean addUser();
    public void updateUser();
    public void deleteUser();
}

实现

public class UserServiceImpl implements UserService {

    @Override
    public boolean addUser() {
        System.out.println("UserServiceDaoImpl addUser");
        return true;
    }

    @Override
    public void updateUser() {
        //测试抛出异常通知
    //  int i=1/0;
        System.out.println("UserServiceDaoImpl updateUser");
    }

    @Override
    public void deleteUser() {
        System.out.println("UserServiceDaoImpl deleteUser");
    }

}

切面类
5种通知对方法的方法名称没有限制,但是方法的格式有限制。方法的格式会在xml配置中给出。

public class MyAspect  {
    //前置通知
    public void before(JoinPoint joinPoint){
        System.out.println("MyAspect-before");
    }
    //终究通知
    public void after(JoinPoint joinPoint){
        System.out.println("MyAspect-after");
    }
    //环绕通知
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("MyAspect-around-前");
        Object obj=joinPoint.proceed();//履行目标方法
        System.out.println("MyAspect-around-后");
        return obj;
    }
    //后置通知
    public void afterReturning(JoinPoint joinPoint,Object ret){
        System.out.println("MyAspect-afterReturning  "+joinPoint.getSignature().getName()+"\t"+ret);
    }
    //异常通知
    public void afterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("MyAspect-afterThrowing "+e.getMessage());
    }
}   

spring配置

<?xml version="1.0" encoding="UTF⑻"?>
<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 
                            http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 创建目标类 -->
    <bean id="userServiceId" class="com.scx.xmlproxy.test.UserServiceImpl"></bean> 
    <!-- 创建切面类(通知) -->  
    <bean id="myAspectId" class="com.scx.xmlproxy.test.MyAspect"></bean>  
    <!-- aop编程--> 
    <aop:config proxy-target-class="true">
        <aop:aspect ref="myAspectId">
            <aop:pointcut expression="execution(* com.scx.xmlproxy.test.*.*(..))" id="myPointCut"/>
            <!-- 前置通知
                <aop:before method="before" pointcut-ref="myPointCut"/>
                方法格式(参数1)
                参数1:连接点描写
                method:方法名
                pointcut:切入点表达式
                pointcut-ref:切入点援用
            -->
            <!-- 终究通知 
                <aop:after method="after" pointcut-ref="myPointCut"/>
                方法格式(参数1)
                参数1:连接点描写
            -->
            <!-- 环绕通知
                    <aop:around method="around" pointcut-ref="myPointCut"/> 
                    方法格式(参数1)
                    参数:org.aspectj.lang.ProceedingJoinPoint
             -->
             <!-- 后置通知
                    <aop:after-returning method="afterReturning" returning="ret" pointcut-ref="myPointCut"/>
                    方法格式(参数1,参数2)
                    参数1:连接点描写
                    参数2:类型Object,参数名 returning="ret" 配置的
            -->
            <!-- 
                抛出异常
                <aop:after-throwing method="afterThrowing" pointcut-ref="myPointCut" throwing="e"/>
                方法格式(参数1,参数2)
                参数1:连接点描写对象
                参数2:取得异常信息,类型Throwable ,参数名由throwing="e" 配置
             -->

        </aop:aspect>


    </aop:config>

</beans>

测试:
测试时,最好只履行1个通知,否则结果会和想象的不1样orz.

@org.junit.Test
    public void testProxy(){
        String xmlPath="com/scx/xmlproxy/test/applicationContext.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
        UserService userService=(UserService) applicationContext.getBean("userServiceId");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

测试结果:
前置通知:
这里写图片描述
后置通知:
这里写图片描述
异常通知:
为了出现异常我在实现类的updateUser方法里面里面添加了int i = 1 /0; 这行代码

这里写图片描述
结果如图所示输出了除0的异常
这时候候我们修改成终究通知。运行结果:
这里写图片描述
我们发现updateUser方法没有由于异常输出,但是终究通知输出了。
环绕通知:
这里写图片描述

注解小例子在写篇文章给出~

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生