Spring的AOP小例子,以及遇到的相关ADVICE代码不起作用为题

在Spring AOP应用中,发现配置的advice未生效。问题在于未正确获取代理对象的bean。AOP原理是通过代理在切入点执行额外逻辑。理解此概念并确保在客户端代码中获取proxy bean是关键。文中分享了学习AOP的经验,并举例介绍了如何使用RegexpMethodPointcutAdvisor进行切点匹配。

在做SPRING 的AOP小例子的时候,配置完成后,所有的AOP的advice实现都不起作用。后来读下面这一篇文章,才恍然大悟。
对于AOP的原理,简单理解,就是在代理对象的各个切入点执行另外的方法。所以,当各种advice方法不执行的时候,应该考虑到AOP的原理,然后在client代码中考虑获取service接口实现的时候,要直接获取proxy的bean。
一个是经验,一个是知识没有成为完整的体系。
下面的文章 来自 ◎筱米加步枪◎.Blog

自己的代码就不贴了,转载一下上面的简单例子:
昨天,做了有关日志的AOP,对相关的AOP知识总结如下:

1.引入AOP(Aspect Oroented Programming) 面向切面编程,是消除代码重复的一种方法。

2.Spring AOP 中提供了两种PointcutAdvisor,分别是:

①org.springframework.aop.support.RegexpMethodPointcutAdvisor (需要加上完整类名,可以用Spring提供的匹配方式)

②org.springframework.aop.support.NameMatchMethodPointcutAdvisor(只需要方法名,不用加类名)

今天,主要来说明下RegexpMethodPointcutAdvisor的用法。贴一个例子来说明,一些说明都写在注释中~看贴的代码:
IPrinter(打印接口)

/**
 * 打印接口
 * @author ChenST
 */
public interface IPrinter {

    /** 打印接口 */
    public void print();
}

PrinterImpl(打印实现类)

/**
 * 打印接口实现类
 * @author ChenST
 */
@Repository
public class PrinterImpl implements IPrinter{

    @Override
    public void print() {
        System.out.println("hello world");
    }
}

AfterPrinter(切入对象)

/**
 * 通知,在执行方法执行后调用该方法
 * @author ChenST
 */
//对应的还有MethodBeforeAdvice等
public class AfterPrinter implements AfterReturningAdvice{

    //第一个参数表示 切入方法的 [返回对象]
    //第二个参数表示 切入方法的 [方法反射对象]
    //第三个参数表示 切入方法的 [参数数组(方法的所有参数组成)]
    //第四个参数表示 [调用该方法的对象]
    @Override
    public void afterReturning(Object returnObject, Method method,
            Object[] argArray, Object callObject) throws Throwable {
        System.out.println("add log:print Hello world");
    }
}

Spring配置文件

<context:annotation-config />
      <context:component-scan base-package="com.shine" />        

      <bean id="printer" class="com.shine.PrinterImpl"/>     
      <bean id="afterPrinter" class="com.shine.AfterPrinter"/>

      <!-- 配置一个拦截器 (切入点对象,确定何时何地调用拦截器)  -->
      <bean id="pointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
         <!-- [通知,特定连接点所采取的动作] -->
         <!-- 加入切面,切面为当执行完print方法后 再执行加入的切面 -->
         <property name="advice">
            <ref local="afterPrinter"/>
         </property>
         <!-- 要拦截的方法,可根据Spring提供匹配方式进行拦截  -->
         <property name="pattern">
                <!--  .表示符合任何单一字元
                 ###  +表示符合前一个字元一次或多次
                 ###  *表示符合前一个字元零次或多次
                 ###  \Escape任何Regular expression使用到的符号
                 -->
                 <!-- .*表示前面的前缀(包括包名) 表示print方法-->
                <value>.*print</value>
         </property>
      </bean>

      <!-- ### 代理工程  -->
      <bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <!-- 指定目标对象,目标对象是PrinterImpl对象 -->
         <property name="target">
            <ref local="printer"/>
         </property>

         <!-- 该目标中加入拦截器pointcutAdvisor -->
         <property name="interceptorNames">
            <list>
                <value>pointcutAdvisor</value>
            </list>
         </property>
      </bean>

测试类

/**
 * 测试类
 */
public class TestMain {

    public static void main(String[] args) {
        ApplicationContext ctx = new FileSystemXmlApplicationContext(
                "classpath:applicationContext.xml");
        // ☆注意:这里的Bean对象获取必须从代理工厂中去取,否则无法切入
        IPrinter printer = (IPrinter) ctx.getBean("proxyFactory");
        printer.print();
    }
}

运行结果

hello world
add log:print Hello world

感觉这么多开源东西中,最需要研究的就是Spring了~~ = =|| 继续study~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值