zoukankan      html  css  js  c++  java
  • spring切面编程AOP 范例一

    参照网上的spring AOP编程实例进行配置,但是碰到了几个坑。这篇文章重点讲解一下我踩过的两个坑:

    1.使用@Service自动装配的时候,基础扫描包配置要正确;

    2.xml中切面配置中的execution表达式的匹配规则要注意;

    针对第一个问题

    是我发现我新建的一个包里面写了一个接口和这个接口的实现,在接口实现上使用@Service,那么在使用这个service的时候,bean会自动注入进来的,但是我写的单测用例一直提示我bean注入失败。我写的其他包里的service就可以正常使用。我突然想起来,spring要识别@Service,是需要扫描基础包的,那应该是我的基础包配置没有将我新建的这个包包含进去。

    applicationContext.xml中最初的配置:  

     <context:component-scan base-package="com.nuomi"/>

    而我新建的包名是:com.baidu.nuomi.crm.mm,果然是不包含在基础包里面的,于是我在applicationContext.xml配置文件中又新加了下面这一行:

    <context:component-scan base-package="com.baidu"/>

    就可以了。第一个问题完美解决。

    下面说下第二个问题

    第一步:写好切面类:

     1 package com.baidu.nuomi.crm.helper.monitorproxy.aspect;
     2 
     3 import org.aspectj.lang.JoinPoint;
     4 import org.aspectj.lang.ProceedingJoinPoint;
     5 
     6 /**
     7  * @author sonofelice
     8  * @version 2015年12月17日 下午1:21:46 类说明 :
     9  */
    10 public class ProxyAspect {
    11     public void doAfter(JoinPoint jp) {
    12         System.out.println("log Ending method:" + jp.getTarget().getClass().getName() + "."
    13                 + jp.getSignature().getName());
    14     }
    15 
    16     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    17         long time = System.currentTimeMillis();
    18         Object retVal = pjp.proceed();
    19         time = System.currentTimeMillis() - time;
    20         System.out.println("process time:" + time + "ms");
    21         return retVal;
    22     }
    23 
    24     public void doBefore(JoinPoint jp) {
    25         System.out.println("long Beginning methoe:" + jp.getTarget().getClass().getName() + "."
    26                 + jp.getSignature().getName());
    27     }
    28 
    29     public void doThrowing(JoinPoint jp, Throwable ex) {
    30         System.out.println("methoe" + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()
    31                 + " throw exception");
    32         System.out.println(ex.getMessage());
    33     }
    34 }
    View Code

    第二步:写好切面要织入的目标对像:

    接口和其对应的实现:

     1 package com.baidu.nuomi.crm.target.asp;
     2 
     3 /**
     4  * @author sonofelice
     5  * @version 2015年12月17日 下午2:49:20 类说明 :
     6  */
     7 public interface AService {
     8 
     9     public void barA();
    10 
    11     public void fooA(String _msg);
    12 }
    13 
    14 package com.baidu.nuomi.crm.target.asp;
    15 
    16 import org.springframework.stereotype.Service;
    17 
    18 /**
    19  * @author sonofelice
    20  * @version 2015年12月17日 下午3:41:05 类说明 :
    21  */
    22 @Service("aService")
    23 public class AServiceImp implements AService {
    24 
    25     @Override
    26     public void barA() {
    27         System.out.println("AServiceImpl.barA()");
    28     }
    29 
    30     @Override
    31     public void fooA(String _msg) {
    32         System.out.println("AServiceImpl.fooA(msg:" + _msg + ")");
    33     }
    34 
    35 }
    View Code

    第三步:xml文件配置:

    首先在spring相关的配置文件中新建一个spring-aspect.xml文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:aop="http://www.springframework.org/schema/aop"
     5        xsi:schemaLocation="http://www.springframework.org/schema/beans
     6       http://www.springframework.org/schema/beans/spring-beans.xsd
     7       http://www.springframework.org/schema/aop
     8       http://www.springframework.org/schema/aop/spring-aop.xsd
     9              ">
    10     <bean id="proxyAspect" class="com.baidu.nuomi.crm.helper.monitorproxy.aspect.ProxyAspect"/>
    11     <aop:config>
    12         <aop:aspect id="doOpAspect" ref="proxyAspect">
    13             <aop:pointcut id="entrance" expression="execution(* com.baidu.nuomi.crm.target.asp.*.*(..))" />
    14             <aop:before pointcut-ref="entrance" method="doBefore"/> 
    15             <aop:after pointcut-ref="entrance" method="doAfter"/>
    16             <aop:around pointcut-ref="entrance" method="doAround"/>
    17             <aop:after-throwing pointcut-ref="entrance" method="doThrowing" throwing="ex"/>
    18         </aop:aspect>
    19     </aop:config>
    20 </beans>

    然后在applicationContext.xml文件中引入上面的配置文件:

    1 <import resource="spring-monitorproxy.xml" />

    第四步:写个单测用例看一下配置是否成功了(我用的是junit)

    下面是我的单测用例:

    1 public class BServiceTest extends BaseTest {
    2     @Autowired
    3     AService aService;
    4     @Test
    5     public void test() {
    6         aService.barA();
    7         aService.fooA("msg");
    8     }
    9 }

    运行结果如下:

    long Beginning methoe:com.baidu.nuomi.crm.target.asp.AServiceImp.barA

    AServiceImpl.barA()

    process time:0ms

    log Ending method:com.baidu.nuomi.crm.target.asp.AServiceImp.barA

    long Beginning methoe:com.baidu.nuomi.crm.target.asp.AServiceImp.fooA

    AServiceImpl.fooA(msg:msg)

    process time:0ms

    log Ending method:com.baidu.nuomi.crm.target.asp.AServiceImp.fooA

    当然,一开始肯定不是这么顺利的出结果的。切面类中的方法中打印的东西在我的控制台中一条都没有打印,这是为什么呢?肯定是切面类没有织入到目标类里面啊。仔细检查下配置文件,跟借鉴的别人的配置是一样的,配置第一行,都是先配置切面类的bean,不同的地方就是这个execution表达式

    <aop:pointcut id="entrance" expression="execution(* com.baidu.nuomi.crm.target.asp.*.*(..))" />

    那应该是我的表达式不正确。参考文章:http://lavasoft.blog.51cto.com/62575/172292/

    任意公共方法的执行:
    execution(public * *(..))
    任何一个名字以“set”开始的方法的执行:
    execution(* set*(..))
    AccountService接口定义的任意方法的执行:
    execution(* com.xyz.service.AccountService.*(..))
    在service包中定义的任意方法的执行:
    execution(* com.xyz.service.*.*(..))
    在service包或其子包中定义的任意方法的执行:
    execution(* com.xyz.service..*.*(..))

    我想要在包asp中的定义的任意方法上执行切面类,就按照对应的规则去配置才可以成功的。

    新手可以参考上面的配置,有问题可以留言。

     

     

  • 相关阅读:
    HTML元素解释
    Java命名规范
    HDU 1058 Humble Numbers(DP,数)
    HDU 2845 Beans(DP,最大不连续和)
    HDU 2830 Matrix Swapping II (DP,最大全1矩阵)
    HDU 2870 Largest Submatrix(DP)
    HDU 1421 搬寝室(DP)
    HDU 2844 Coins (组合背包)
    HDU 2577 How to Type(模拟)
    HDU 2159 FATE(二维完全背包)
  • 原文地址:https://www.cnblogs.com/sonofelice/p/5054643.html
Copyright © 2011-2022 走看看