spring学习笔记(十):使用 XML 方式实现 AOP 编程


接上一篇 spring学习笔记(九):使用注解方式实现 AOP 编程


接口 IUserDao.java:

public interface IUserDao {
    void save();
}

目标对象类型 UserDao.java,实现 IUserDao 接口:

/**
 * 目标对象:实现 IUserDao 接口,spring 会自动选择 JDK代理
 */
public class UserDao implements IUserDao{
    @Override
    public void save() {
        System.out.println("------ 保存数据 -----");
    }
}

目标对象类型 OrderDao.java,不实现接口:

/**
 * 目标对象:没有实现接口,spring 会自动选择 cglib 代理
 */
public class OrderDao {
    public void save() {
        System.out.println("------ 保存数据 -----");

        // 当目标方法执行异常时,会执行 @AfterThrowing 注解,此时 @AfterReturning 注解不会执行;
        // @After 注解不管目标方法有没有异常,都会执行。
        int i = 1 / 0;
    }
}

切面类 Aop.java:

/**
 * 切面类
 */
public class Aop {
    public void begin(){
        System.out.println("开启事务...");
    }

    public void after(){
        System.out.println("提交事务...");
    }

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

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

    public void around(ProceedingJoinPoint pjo) throws Throwable {
        System.out.println("环绕前...");    // 在执行目标方法之前执行
        pjo.proceed();                      // 执行目标方法
        System.out.println("环绕后...");    // 在执行目标方法之后执行
    }

}

配置文件 bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 创建目标对象 -->
    <bean id="userDao" class="com.spring.demo.UserDao"/>
    <bean id="orderDao" class="com.spring.demo.OrderDao"/>

    <!-- 创建 AOP 对象 -->
    <bean id="aop" class="com.spring.demo.Aop"/>

    <!-- AOP 配置 -->
    <aop:config>
        <!-- 定义一个切入点表达式:指定拦截哪些方法 需要动态植入切面代码 -->
        <aop:pointcut expression="execution(* com.spring.demo.*.*(..))" id="pointCut"/>
        <!-- 指定切面类 -->
        <aop:aspect ref="aop">
            <!-- 前置通知:在执行目标方法之前执行(引用前面定义的 切入点表达式) -->
            <aop:before method="begin" pointcut-ref="pointCut"/>
            <!-- 后置通知:在执行目标方法之后执行(无论是否出现异常,最后都会执行) -->
            <aop:after method="after" pointcut-ref="pointCut"/>
            <!-- 返回后通知:在调用目标方法结束后执行(出现异常不执行) -->
            <aop:after-returning method="afterReturning" pointcut-ref="pointCut"/>
            <!-- 异常通知:当目标方法出现异常时执行 -->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointCut"/>
            <!-- 环绕通知:环绕目标方法执行(相当于 前置通知 + 后置通知) -->
            <aop:around method="around" pointcut-ref="pointCut"/>
        </aop:aspect>
    </aop:config>

</beans>

 测试程序 Demo.java:

public class Demo {
    // 如果目标对象有实现接口,spring 会自动选择 “JDK代理”
    @Test
    public void testJDK(){
        // 加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

        // 从 IOC 容器中获取对象
        IUserDao userDao = (IUserDao) context.getBean("userDao");
        System.out.println(userDao.getClass());
        userDao.save();
    }

    // 如果目标对象没有实现接口,spring 会自动选择 “Cglib代理”
    @Test
    public void testCglib(){
        // 加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

        // 从 IOC 容器中获取对象
        OrderDao orderDao = (OrderDao) context.getBean("orderDao");
        System.out.println(orderDao.getClass());
        orderDao.save();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值