Spring学习——AOP由xml实现

前面有一篇利用Annotation实现AOP,现在记录一下通过XML来实现该功能。

以下过程中,前期准备与上一篇Spring学习——AOP由Annotation实现类似,可以简单看一下。

1、 在beans.xml的基本属性

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

    <!-- 打开Spring的Annotation -->
    <context:annotation-config/>

    <!-- 设定Spring去哪些包中找Annotation -->
    <context:component-scan base-package="spring"/>

</beans>

2、创建一个需要实现动态代理的类

//实现代理的类
public class LogAspect {

    public void logStart() {
        Logger.info("加入日志");
    }

}

//这个是功能类
public class Logger {

    public static void info(String info) {
        System.out.println("----" + info);
    }

}

3、导入aspect包

Spring使用的是AspectJ包来实现AOP的,所以需要导入这个包

AspectJ包下载教程

4、注解声明

不同于使用Annotation方式实现AOP,xml实现方式,只需要告知Spring,LogAspect的存在就可以。


@Component("logAspect")
public class LogAspect {


    public void logStart(JoinPoint jPoint) {
        //得到执行的对象
        System.out.println(jPoint.getTarget());
        //得到执行的方法
        System.out.println(jPoint.getSignature().getName());
        Logger.info("加入日志");
    }


    public void logEnd(JoinPoint jPoint) {
        Logger.info("方法调用结束");
    }



    public void logAround(ProceedingJoinPoint jPoint) {

        Logger.info("开始在Around加入日志");
        try {
            //执行方法
            jPoint.proceed(); 
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Logger.info("结束Around");
    }

}

5、xml中配置

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

    <!-- 打开Spring的Annotation -->
    <context:annotation-config />

    <!-- 设定Spring去那些包中找Annotation -->
    <context:component-scan base-package="spring" />

    <aop:config>
        <!-- 定义切面 -->
        <aop:aspect id="myLogAspect" ref="logAspect">
            <!-- 在那些位置加入相应的Aspect -->
            <aop:pointcut
                expression="execution(* spring.dao.*.add*(..))||execution(* spring.dao.*.delete*(..))"
                id="logPointCut" />
                <aop:before method="logStart" pointcut-ref="logPointCut"/>
                <aop:after method="logEnd" pointcut-ref="logPointCut"/>
                <aop:around method="logAround" pointcut-ref="logPointCut"/>
        </aop:aspect>
    </aop:config>

</beans>

测试

spring.dao中的类

接口

public interface IUserDao {

    public void add(User user);

    public void delete(int id);

    public User load(int id);

}

实现类

@Repository("userDao")
public class UserDao implements IUserDao {

    @Override
    public void add(User user) {
        System.out.println("添加了 " + user.getName());
    }

    @Override
    public void delete(int id) {
        System.out.println("删除了" + id);
    }

    @Override
    public User load(int id) {
        System.out.println("加载了 " + id);
        return null;
    }

}
测试方法
    @Test
    public void testUser01() {
        IUserDao dao=(IUserDao) factory.getBean("userDao");
        User user = new User(1,"猴子");
        dao.add(user);
    }
测试结果
spring.dao.UserDao@2d0399f4
add
----加入日志
----开始在Around加入日志
添加了 猴子
----结束Around
----方法调用结束

顺序问题

如果看过上一篇文章,应该还记得,@Around里面有proceed方法,如果不执行,则不会执行方法。上一篇的结果是拦截了@Before的响应。
这次我们也将方法屏蔽,结果为:

spring.dao.UserDao@2d0399f4
add
----加入日志
----开始在Around加入日志
----结束Around
----方法调用结束

上面两个结果对比后发现,logStart方法执行了,并且在logAround方法之前执行。这样和上一篇得出来的结论不一致,所以我调换了beans.xml里面的顺序:

    <aop:around method="logAround" pointcut-ref="logPointCut"/>
    <aop:before method="logStart" pointcut-ref="logPointCut"/>
    <aop:after method="logEnd" pointcut-ref="logPointCut"/>

测试结果:

----开始在Around加入日志
----结束Around
----方法调用结束

即如果<aop:aroud/><aop:before/>之前,则如果不调用proceed方法,<aop:before/>不会响应。

最后

具体使用哪种方式,取决于个人习惯,上面的顺序问题,只是记录下来,提醒一下可能存在这种问题,其并不会对项目有多大影响。
如果有错误,请留言指出,我会第一时间回复并修改。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值