zoukankan      html  css  js  c++  java
  • Spring入门4.AOP配置深入

    Spring入门4.AOP配置深入

    代码下载 链接: http://pan.baidu.com/s/11mYEO 密码: x7wa

    前言:

             之前学习AOP中的一些概念,包括连接点、切入点(pointcut),切面(Aspect),Advice,Proxy代理等等,同时学历了使用XML配置AOP的方式,这一个过程中遇到很多的错误,比如配置文件中的<aop:aspect-autoproxy/>,如果在配置中没有添加这一行配置,就会编译出错。还有学习Advice的5种方式以及配置原理。

             这一次我们深入的学习XML配置的内容,然后是Annotation的配置方式。

    一、XML配置方式深入

    1.配置切入点

             配置切入点的时候需要给出属性pointcut的属性值,指定切入点表达式。同时还可以使用<aop:pointcut/>元素在<aop:config>中单独的定义切入点,实际上就是为切入点起一个名字,在后面多个Advice中使用。

    <aop:config proxy-target-class=”true”>

             <aop:pointcut id = “mypointcut1” expression=”execution(* com.yang.service.*(..))”/>

             <aop:aspect id=”adviceAspect” ref=”aspectBean”>

                       <aop:before methos=”methodName” pointcut-ref=”mypointcut1”/>

             </aop:aspect>

    </aop:config>

    这样就可以重复使用了,对于精简代码十分有帮助。

    2.切入点指示符

             SpringAOP提供了多种切入点指示符来定义切入点的规则。切入点知识符用于标明一个连接点在什么条件下关联到切入点。切入点表达式就是通过切入点指示符进行定义的,如execution就是一种切入点指示符。

             在Spring3中的切入点指示符有:

             execution:用于匹配执行方法的连接点,他是SpringAOP中最主要的切入点指示符。

             within:限定匹配特定类型的连接点,当使用Spring AOP的时候,只能匹配方法执行的连接点;只可以使用包名进行匹配,比如within(com.yang.service..*)

             this:用于限定AOP代理必须是指定类型的实例,用于匹配该对象的所有连接点。当使用SpringAOP的时候,只能匹配方法执行的连接点.比如this(com.yang.service.UserService)

             target:用于限定目标对象必须是指定类型的实例,用于匹配该对象的所有连接点。当使用SpringAOP的时候,只能匹配方法执行的连接点。

             args:用于对连接点的参数类型进行限制,要求参数类型是指定类型的实例。Spring AOP值能够匹配方法执行的连接点。

             execution表达式的语法格式如下:

             execution(

    modifiers-pattern? 指定方法的修饰符,支持通配符,可以省略             Return-typepatterns  指定方法的返回值类型,支持通配符, 可以使用* 通配符匹配所有类型的返回值类型

    declaring-type-pattern?  指定方法所属的类,支持通配符,可以省略

    Name-pattern(param-pattern) 指定匹配的方法名,支持通配符,可以使用*匹配所有的方法,其中的param-pattern指的是参数类型,支持两种通配符,一种是*,表示一个任意类型的参数;另一个是..,表示的是0个或者是多个任意类型的参数

    throws-pattern?  表示指定的方法声明抛出异常,支持通配符,可以省略)

    通过方法签名定义切入点:

             execution(public       *       *(..)) :匹配目标类所有的public方法

             execution(* find*(..))

    通过类定义切入点,通过包定义切入点,通过方法形参定义切入点

    execution(* com.yang.service.UserService+.*(..)) +表示其接口还有其实现子类中的方法

    execution(* com..*.yang.service.*(..))表示包括子包

    同时可以使用组合表达式&& || !将多个切入点表达式组合起来。

    二、基于Annotation配置的AOP

             其实掌握了XML方式配置的AOP之后,转换成为Annotation方式是十分容易的。AspectJ是一个基于Java语言的AOP框架,他扩展了标准的Java,从语言层面上提供了更加强大的AOP功能。AspectJ是AOP的实现之一,对整套的AOP机制都有着很好的实现机制,所以不使用Spring也可以直接使用AspectJ进行切面编程。从Spring2开始,就已经将AspectJ集成在Spring中。AspectJ允许使用Annotation来定义切面(Aspect)、切入点(pointcut)、增强(Advice)。Spring框架根据这些Annotation来生成对应的AOP代理。

    1.配置切面在Spring配置文件中需要添加

             <aop:aspectj-autoproxy/>

             增加上述配置之后,Spring会根据注解判断一个Bean是否使用了一个或者多个切面,然后自动生成相对应的AOP代理以及拦截器方法调用,并且确认Advice是否如期进行。这里使用注解的方式,需要增加两个AspectJ的类库aspectjweaver.jar&& aspectjrt.jar

    2.声明切面

    在创建的AspectBean类前面声明是切面,使用如下方式:

    @Aspect

    public class AspectBean{}

    3.配置Advice

             AspectJ有一下几种配置方法,这些注解的存留期是RetentionPolicy.RUNTIME,注解目标都是ElementType.METHOD

             AspectJ提供的几种注解方式:

             @Before 成员有value指定一个切入点表达式,也可以指定一个已经存在的切入点

             @AfterReturning value、 returning 表示目标对象返回值绑定给增强的方法, pointcut会覆盖

             @Around value切入点表达式

             @AfterThrowing value 切入点表达式 pointcut覆盖掉value, throwing将抛出的异常绑定到增强的方法

             @After value

    4配置切入点

             使用@Pointcut进行生命,一个切入点的声明有两个部分组成,包含名字和任意参数的签名和切入点表达式。

    @Aspect

    public class AspectBean {

        //@Before(value="execution(* com.yang.service.UserService.*(..))")

       

        @Pointcut("execution(* com.yang.service.UserService.*(..))")

        private void crud(){}

       

        @Before(value="crud")

        public void checkAuth(){

            System.out.println("AspectBean.checkAuth()");

        }

    }

    源代码:

    UserService.java

    package com.yang.service;

     

    public interface UserService {

        public void del();

        public void add();

        public void update();

        public Object select();

    }

    UserServiceImpl.java

    package com.yang.service.impl;

     

    import com.yang.service.UserService;

     

     

    public class UserServiceImpl implements UserService {

     

        @Override

        public void del() {

            System.out.println("UserServiceImpl.del() function ");

        }

     

        @Override

        public void add() {

            System.out.println("UserServiceImpl.add() function ");

        }

     

        @Override

        public void update() {

            System.out.println("UserServiceImpl.update() function ");

        }

     

        @Override

        public Object select() {

            System.out.println("UserServiceImpl.select() function ");

            return null;

        }

    }

    AspectBean.java

    import org.aspectj.lang.ProceedingJoinPoint;

     

     

    //@Aspect

    public class AspectBean {

        //@Before(value="execution(* com.yang.service.UserService.*(..))")

       

        //@Pointcut("execution(* com.yang.service.UserService.*(..))")

        private void crud(){}

       

        //@Before(value="crud")

        public void checkAuth(){

            System.out.println("AspectBean.checkAuth()");

        }

       

        public void release(){

            System.out.println("AspectBean.release()");

        }

       

        public void log(Object result){

            System.out.println("AspectBean.log()");

            if(result==null){

                System.out.println("database have result");

            }else{

                System.out.println("database has no result");

            }

           

        }

       

        public void processException(Throwable ex){

            System.out.println("Exception information:" + ex.getMessage());

        }

       

        public void proceedInTrans(ProceedingJoinPoint joinpoint) throws Throwable{

            System.out.println("start transtraction");

            joinpoint.proceed();

            System.out.println("end transtraction");

        }

    }

    bean.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:tx="http://www.springframework.org/schema/tx"

        xsi:schemaLocation="

            http://www.springframework.org/schema/beans

            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

            http://www.springframework.org/schema/aop

            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

            http://www.springframework.org/schema/tx

            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"

            default-lazy-init="true">

        <aop:aspectj-autoproxy/>

       

        <bean id="aspectBean" class=" com.yang.aspect.AspectBean"></bean>

        <bean id="userService" class="com.yang.service.impl.UserServiceImpl"></bean>

       

        <aop:config proxy-target-class="true">

            <aop:aspect id="myadvice" ref="aspectBean">

                <aop:before method="checkAuth" pointcut="execution(* com.yang.service.UserService.*(..))"/>

               

                <aop:after-returning method="log" pointcut="execution(* com.yang.service.UserService.select(..))" returning="result"/>

               

                <aop:after-throwing method="processException" pointcut="execution(* com.yang.service.UserService.*(..))" throwing="ex"/>

               

                <aop:around method="proceedInTrans" pointcut="execution(* com.yang.service.UserService.*(..))"/>

               

                <aop:after method="release" pointcut="execution(* com.yang.service.UserService.*(..))"/>

               

            </aop:aspect>

        </aop:config>

    </beans>

    TestMain.java

    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

            //System.out.println("before");

           

    UserService userService = (UserService) context.getBean("userService");

    System.out.println("=======================================");

    userService.add();

    System.out.println("=======================================");

    userService.select();

    System.out.println("=======================================");

    YangTengfei

    2013.11.26

    补充知识:

        记得自己在S2SH框架整合的时候,遇到的一个问题,其实是因为自己对于前面知识掌握的不怎么到位,以至于在S2SH整合的时候因为一个小小的知识点的错误,而导致了我找了4个小时的错误才依旧是没有找出来。

        先说一下自己的错误:在S2SH框架整合的时候,最后一步关于实现S2SH框架中的事务机制,我们使用的是Hibernate的HibernateTransactionManager,然后配置了事务的切入点:具体配置如下:

        <!-- S2SH配置的 Hibernate 的事物管理器 -->

        <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

            <property name="sessionFactory" ref="sessionFactory"/>

        </bean>

        <!--  配置事务的Advice,指定事务管理器 -->

        <tx:advice id="txAdvice" transaction-manager="txManager">

            <!-- 配置事务的详细定义 -->

            <tx:attributes>

                <tx:method name="add*" rollback-for="Exception"/>

                <tx:method name="*" />

            </tx:attributes>

        </tx:advice>

        <aop:config>

            <!-- 配置切入点信息,并且将它和切面整合 -->

            <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.yang.s2s.service.impl.*.*(..))"/>

        </aop:config>

    强敌出现:

        在这个配置中,启动Tomcat服务器总是出错,然后就是各种错误说是dataSource出错,然后我们尝试各种方法总是找不到错误,悲了个剧,纠结了4个小时还是不可以。原因是我么配置的pointcut的表达式错误。

        回顾配置这个的切入点的规范:

    execution (

    modifiers-pattern?

    return-type-pattern

    declaring-type-pattern?

    Name-pattern(param-pattern)

    throw-pattern?

    )

    其中的name-pattern * 表示包下的所有类,之后必须还有一个匹配方法,因为配置事务的基本单位是方法而不是类。所以需要修改成为 execution(* com.yang.s2s.service.impl.*Impl.*(..))表示的是任何返回值类型的 在com.yang.s2s.service.impl.包下的以Impl结尾的Class中的任意方法,其中参数也是任意的。

    Add by YangTengfei

    2013.12.02

  • 相关阅读:
    #从零开始学Swift2.0# No.4 枚举, 元组, 数组和字典
    #从零开始学Swift2.0# No.3 基本数据类型
    #从零开始学Swift2.0# No.2 运算符和表达式
    #从零开始学Swift2.0# No.1 初识Swift
    MacOS下SVN的使用
    在Xcode中制作.a文件
    在Xcode中制作Framework
    Objective-C中的Runtime
    汉语字典或者词典的简单的ios小demo
    ios开发-UI进阶-核心动画-时钟动画小案例
  • 原文地址:https://www.cnblogs.com/hbhzsysutengfei/p/3473185.html
Copyright © 2011-2022 走看看