猿蜕变15——Spring AOP怎么用看过来就好了

看过之前的蜕变系列文章,相信你对mybatis有了应用方面的认识。但是这些要完成你的蜕变还不够,考虑到大家的基础知识,我们继续回到spring的话题上来,我们一起聊一聊AOP。

猿蜕变同样是一个原创系列文章,帮助你从一个普通的小白,开始掌握一些行业内通用的框架技术知识以及锻炼你对系统设计能力的提升,完成属于你的蜕变,更多精彩内容,敬请大家关注公主号猿人工厂,点击猿人养成获取

Spring当然是支持AOP这种编程思想的。AspectJ也是一个AOP的编程框架,实现简洁,使用方便,并且支持注解方式,Spring在2.0版本以后AspectJ的AOP实现纳入了自己阵营,只不过在代码将织入这一个步骤,还是需要有Spring AOP的方式去完成。一般来说,使用Spring的AOP模块,在一般使用的是AspectJ的实现方式。

接下来我们就用一个xml方式的例子,来做一个AOP编程。

修改pom.xml增加依赖:

<!--  使用AOP加入aspectj依赖-->       <dependency>                     <groupId>org.aspectj</groupId>                     <artifactId>aspectjweaver</artifactId>                     <version>1.7.4</version>              </dependency>   <!--  使用AOP加入Spring对AOP的aspectj的支持依赖-->              <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-aspects</artifactId>        <version>4.1.2.RELEASE</version>    </dependency>

代码示例:

为了演示效果,给TravelRouteService增加方法:

package com.pz.study.frame.spring.service; import java.util.List; import com.pz.study.frame.spring.domain.TravelRoute;  /** * 线路Service */public interface TravelRouteService {      /**     * 根据id查询     * @param rid     * @return     */    public TravelRoute findTravelRouteById(StringtravelRouteId);          /**     * 需改线路     * @param rid     * @return     */    public TravelRoute updateTravelRouteById(StringtravelRouteId);          /**     * 删除线路     * @param rid     * @return     */    public TravelRoute deleteTravelRouteById(StringtravelRouteId);       /**     * 分页查询线路列表     * @param startRow     * @param endRow     * @return     */    public List<TravelRoute>findTravelRouteByPage(int startRow ,int endRow);       /**     * 增加线路     * @param travelRoute     * @throws Exception     */    public void addTravelRoute(TravelRoute travelRoute) throws Exception;}

修改实现类:

package com.pz.study.frame.spring.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.pz.study.frame.spring.domain.TravelRoute;import com.pz.study.frame.spring.manager.TravelRouteManager;import com.pz.study.frame.spring.service.TravelRouteService;package com.pz.study.frame.spring.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.pz.study.frame.spring.domain.TravelRoute;import com.pz.study.frame.spring.manager.TravelRouteManager;import com.pz.study.frame.spring.service.TravelRouteService; @Service(value="TravelRouteService")public class TravelRouteServiceImpl implements TravelRouteService {             @Resource(name="travelRouteManager")       private TravelRouteManager travelRouteManager;             public TravelRouteServiceImpl(){              System.out.println("TravelRouteServiceImpl被实例化了");       }        @Override       public TravelRoute findTravelRouteById(StringtravelRouteId) {              System.out.println("=====findTravelRouteById=====被执行了");              returntravelRouteManager.findTravelRouteById(travelRouteId);       }                                  @Override       public TravelRoute updateTravelRouteById(StringtravelRouteId) {                           System.out.println("=====updateTravelRouteById=====被执行了");              returnnull;                                  }        @Override       public TravelRoute deleteTravelRouteById(StringtravelRouteId) {              System.out.println("=====deleteTravelRouteById=====被执行了");              returnnull;                                  }        @Override       public List<TravelRoute>findTravelRouteByPage(int startRow, int endRow) {              System.out.println("=====findTravelRouteByPage=====被执行了");              return null;       }                    @Override       public void addTravelRoute(TravelRoute travelRoute) throws Exception {                           System.out.println("=====addTravelRoute=====被执行了");                           thrownew Exception("addTravelRoute===Exception");                    }        public void init() {          System.out.println("我是初始方法init我被执行了");       }        public void destroy() {          System.out.println("我是销毁方法destroy我被执行了");       }        public void setTravelRouteManager(TravelRouteManager travelRouteManager) {              this.travelRouteManager = travelRouteManager;       }             } 

编写切面类FristAspect:

package com.pz.study.frame.spring.aspect; import org.aspectj.lang.ProceedingJoinPoint; public class FristAspect {        public void before() {              System.out.println("===before====方法前增强========");       }        public void after() {              System.out.println("===after=====最终增强========");       }        public void afterThrowing(Exception e) {              System.out.println("===afterThrowing=====异常通知========:" + e);       }        public void afterReturning(int result) {              System.out.println("===afterReturning=====返回后通知增强========" + result);       }        public Object around(ProceedingJoinPoint pjp) throws Throwable {              System.out.println("===around=====环绕增强:前========:");              Object proceed = pjp.proceed();              System.out.println("===around=====环绕增强:后========:");               return proceed;       }}

编写Spring AOP相关的配置文件spring-aop.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:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/aop       http://www.springframework.org/schema/aop/spring-aop.xsd       http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">        <!-- 注入Aspect实现类 --><bean id="fristAspect"class="com.pz.study.frame.spring.aspect.FristAspect"/>   <!-- 注入Aspect实现类 -->    <bean id="fristAspect"class="com.pz.study.frame.spring.aspect.FristAspect"/>      <!--配置aop-->    <aop:config>        <!--定义切入点-->        <aop:pointcut id="addTravelRoutePointcut" expression="execution(* com.pz.study.frame.spring.service.impl.TravelRouteServiceImpl.addTravelRoute(..))"/>        <aop:pointcut id="updateTravelRouteByIdPointcut" expression="execution(*com.pz.study.frame.spring.service.impl.TravelRouteServiceImpl.updateTravelRouteById(..))"/>        <aop:pointcut id="deleteTravelRouteByIdPointcut" expression="execution(*com.pz.study.frame.spring.service.impl.TravelRouteServiceImpl.deleteTravelRouteById(..))"/>        <aop:pointcut id="findTravelRouteByIdPointcut" expression="execution(* com.pz.study.frame.spring.service.impl.TravelRouteServiceImpl.findTravelRouteById(..))"/>        <aop:pointcut id="findTravelRouteByPagePointcut" expression="execution(* com.pz.study.frame.spring.service.impl.TravelRouteServiceImpl.findTravelRouteByPage(..))"/>         <!--定义切面-->        <aop:aspect ref="fristAspect">            <!--前置增强-->            <aop:before method="before" pointcut-ref="updateTravelRouteByIdPointcut"/>            <!--后置增强-->            <aop:after-returning method="afterReturning" pointcut-ref="deleteTravelRouteByIdPointcut" returning="result"/>            <!--异常增强-->            <aop:after-throwing method="afterThrowing" pointcut-ref="addTravelRoutePointcut" throwing="e"/>            <!--最终增强-->            <aop:after method="after"pointcut-ref="findTravelRouteByIdPointcut"/>            <!--环绕增强-->            <aop:around method="around" pointcut-ref="findTravelRouteByPagePointcut"/>        </aop:aspect>    </aop:config>

不要忘记在applicationContext.xml引入新增的配置文件噢

  <importresource="spring-aop.xml"/>

编写测试用例感受下效果:

@Test       public void testAop(){                            ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");                              TravelRouteController travelRouteController=(TravelRouteController)applicationContext.getBean("travelRouteController");               TravelRouteServicetravelRouteService=(TravelRouteService) applicationContext.getBean("travelRouteService");                              travelRouteService.findTravelRouteById("testAop");               travelRouteService.updateTravelRouteById("testAop");               travelRouteService.deleteTravelRouteById("testAop");               travelRouteService.findTravelRouteByPage(0,10);                              try {                     travelRouteService.addTravelRoute(new TravelRoute());              } catch (Exception e) {                     // TODO Auto-generated catch block                     e.printStackTrace();              }                                 }

===after=====最终增强========

===before====方法前增强========

=====updateTravelRouteById=====被执行了

=====deleteTravelRouteById=====被执行了

===around=====环绕增强:前========:

=====findTravelRouteByPage=====被执行了

===around=====环绕增强:后========:

=====addTravelRoute=====被执行了

===afterThrowing=====异常通知========:java.lang.Exception: addTravelRoute===Exception

<aop:config>标签,定义了一组AOP的配置。

<aop:ponintcut>子标签,定义切入点,id表示切入点的唯一编号,expression为切入点的值,需要满足excution表达式

<aop:aspect>自标签的ref属性,指定使用那个切面。

<aop:before>定义前置增强,method为切面bean中的方法名,指定使用切面中的方法来实现增强。

<aop:after>定义最终增强,method为切面bean中的方法名,指定使用切面中的方法来实现增强。

<aop:after-returning>定义返回后增强,method为切面bean中的方法名,指定使用切面中的方法来实现增强。

<aop:after-throwing>定义异常发生增强,method为切面bean中的方法名,指定使用切面中的方法来实现增强。

<aop:around>定义环绕增强,method为切面bean中的方法名,指定使用切面中的方法来实现增强。

 AspectJ提供了excution表达式用于定义切入点,表达式语法如下:

execution (

   [modifiers-pattern]  访问权限类型

    ret-type-pattern  返回值类型

   [declaring-type-pattern]  全限定性类名

   name-pattern(param-pattern)  方法名(参数名)

    [throws-pattern]  抛出异常类型

)

切入点的定义需要匹配目标的方法名,使用excution表达式时,[ ]的部分是可以省略的,各部间使用空格分隔。

下面是一些表达式的例子。

举例:

execution(public * *(..))

表单式含义:任意公共方法。

execution(* set*(..))

表单式含义:任何一个以“set”开始的方法。

execution(* com.pz.study.frame.spring.service*.*(..))

表单式含义:定义在 com.pz.study.frame.spring.service 包里的所有类和方法。

execution(* com.pz.study.frame.spring.service..*.*(..))

表单式含义:定义在 com.pz.study.frame.spring.service包或者子包里的所有类和方法。

注意:“..”出现在表达式中时,后面必须跟“*”,表示包、子包下的所有类。

execution(* *.service.*.*(..))

表单式含义:只有一级包下的 serivce 子包下所有类(接口)中所有方法为切入点

execution(* *..service.*.*(..))

表单式含义:所有包下的 serivce 子包下所有类(接口)中所有方法为切入点

execution(* *.IService.*(..))

表单式含义:一级包下的 IService接口中所有方法为切入点

execution(* *.. IService.*(..))

表单式含义:所有包下的 IService接口中所有方法为切入点

execution(*com.pz.study.frame.spring.service.TravelRouteService.*(..))

表单式含义:com.pz.study.frame.spring.service.TravelRouteService 接口中的所有方法。

execution(*com.pz.study.frame.spring.service.TravelRouteService+.*(..))

表单式含义:com.pz.study.frame.spring.service.TravelRouteService若为接口,则为接口中的所有方法及其所有实现类中的所有方法;若为类,则为该类及其子类中的所有方法。

我建了一个技术群,群里有很多高手,加小编微信,备注:学习。带你见识更多的高手,帮你快速成长。

猜你喜欢

转载自blog.csdn.net/hzldds2019/article/details/106658050
今日推荐