为了账号安全,请及时绑定邮箱和手机立即绑定

Spring 一二事(9) - xml 形式的 AOP

标签:
Java

AOP在spring中是非常重要的一个

在切面类中,有5种通知类型:

aop:before 前置通知

aop:after-returning 后置通知

aop:after 最终通知

aop:after-throwing 异常通知

aop:around 环绕通知

<bean id="personDAO" class="com.lee.spring002.aop.xml.PersonDAOImpl"></bean>
    <bean id="transaction" class="com.lee.spring002.aop.xml.Transaction"></bean>

    <aop:config >
        <!-- 切入点表达式,作用:确定目标类 -->
        <!-- spring 会自动检测这个表达式下的类是否是切面,如果是,则不会包含进来 -->
        <aop:pointcut expression="execution(* com.lee.spring002.aop.xml.PersonDAOImpl.*(..))" id="perform"/>
        <!-- ref 指向切面 -->
        <aop:aspect ref="transaction">
            <!-- 前置通知 -->
            <aop:before method="beginTransaction" pointcut-ref="perform"/>

            <!-- 
                后置通知
                    可以获取目标方法的返回值(前置方法获取不到)
                    如果目标方法抛出异常,后置通知则不会继续执行
             -->
            <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>

            <!-- 
                最终通知
                    无论目标方法是否抛出异常都将执行此方法
             -->
             <aop:after method="finallyDisplay" pointcut-ref="perform"/>

             <!-- 
                 异常通知
              -->
              <aop:after-throwing method="exception" pointcut-ref="perform" throwing="content"/>

              <!-- 
                  环绕通知
                      能控制目标方法能否执行
                      前置通知和后置通知能在目标方法的前后加代码,但是不能控制方法的执行
               -->
               <aop:around method="arround" pointcut-ref="perform"/>
        </aop:aspect>
    </aop:config>

IPersonDAO.java

1 package com.lee.spring002.aop.xml;
2 
3 public interface IPersonDAO {
4     public String savePerson();
5 }

PersonDAOImpl.java

package com.lee.spring002.aop.xml;

public class PersonDAOImpl implements IPersonDAO {

    @Override
    public String savePerson() {
        System.out.println("PersonDAOImpl - savePerson()");

//        int a = 1 / 0;

        return "save successfully";
    }

}

Transaction.java

package com.lee.spring002.aop.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 这是个切面
 * 
 * @author leechenxiang
 * @date 2016年1月12日
 *
 */
public class Transaction {

    public void beginTransaction(JoinPoint jp) {
        System.out.println("连接点名称: " + jp.getSignature().getName());
        System.out.println("目标类名称: " + jp.getTarget().getClass());
        System.out.println("Begin transaction...");
    }

    /**
     * 
     * @param jp
     * @param val 目标方法返回值,要与returning对应 
     */
    public void commit(JoinPoint jp, Object val) {
        System.out.println("Transaction commit...");

        System.out.println("returning: " + val.toString());
    } 

    public void finallyDisplay() {
        System.out.println("finally...");
    }

    public void exception(JoinPoint jp, Throwable content) {
        System.out.println("exception: " + content);
        System.out.println("exception: " + content.getMessage());
    }

    public void arround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("arround...");
        pjp.proceed();    // 调用目标方法,如果这行不写,则目标方法不执行
    }
}

测试:

package com.lee.spring002.aop.xml;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionTest {

    /**
     * 原理:
     *    1、当spring容器启动的时候,加载两个bean,对两个bean进行实例化
     *    2、当spring容器对配置文件解析到<aop:config>的时候
     *    3、把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean
     *    4、如果匹配成功,则为该bean创建代理对象
     *    5、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象
     *         如果没有代理对象,则返回对象本身
     */
    @Test
    public void testPerson() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        IPersonDAO personDAO = (IPersonDAO)context.getBean("personDAO");
        personDAO.savePerson();
    }

}
点击查看更多内容
“小礼物走一走,来慕课关注我”
赞赏支持
风间影月说 去围观
创业公司技术总监, 10年+开发和技术管理经验。SUN认证SCJP、PMP、MCP认证。主要从事后端技术和架构领域,有丰富的电商平台与物流平台核心系统的架构设计和开发经验。
评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
1.2万
获赞与收藏
904

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消