zoukankan      html  css  js  c++  java
  • springAOP

    springAOP

    一、IOC

    IOC叫控制反转,对象的创建由外部框架来实现,控制权交给了外部容器,控制发生了反转,也叫依赖注入,程序中需要对象,则依赖外部框架把对象进行注入。IOC是一个容器,对象被创建之后都存储在这个容器中,对象默认是单例模式,可以通过scope这个属性来改变。对象的配置可以在配置文件中处理,也可以运用注解的方式来创建对象,程序通过ApplicationContext.getBean()这个方法来获取对象,也可以通过注解@Autowired@Resource(name="stu12")自动注入。如果是通过注解的方式来自动创建Bean,则配置文件要启动注解并扫描相关的包,类前还需要添加相关的注解: @Service@Component@Controller@Repository

    二、AOP

    面向切面编程,对于程序内部进行横切关注,把公共的代码抽取出来,形成切面,再通过连接点去监听指定方法的执行情况,在方法执行过程中把切面织入到被监听的方法中去。方法被动的被执行某些功能代码。

    三、相关概念:

    Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象.

    joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)

    Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.

    Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知

    Target(目标对象):代理的目标对象

    Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.

    Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

    四、AOP运用

    1. 添加相关的jar

    aopalliance-1.0.0.jar

    aspectjweaver-1.6.8.jar

    commons-logging-1.1.1.jar

    spring-aop-4.3.10.RELEASE.jar

    spring-aspects-4.3.10.RELEASE.jar

    spring-beans-4.3.10.RELEASE.jar

    spring-context-4.3.10.RELEASE.jar

    spring-core-4.3.10.RELEASE.jar

    spring-expression-4.3.10.RELEASE.jar

    1. 把方法的公共抽取出来形成切面类及通知

    @Component  //扫描到IOC容器中去

    @Aspect  //表示这个类是一个切面类

    public class LogInfo {

    /* execution(public springAOP0305.Calc.*(int, int))切面表达式,指定要监听的方法

     *  springAOP0305.Calc.* 是一个通配符,任何方法都行,int,int是方法的参数,必须是两个int型才监听。

     *  可以改成.. 表示任意类型,任意数量的参数都行

     */

    //前置通知,在监听的方法执行前执行..

    @Before("execution(* springAOP0305.*.*(..))")

    public void before() {

    System.out.println("方法开始执行.......... ");

    }

    //后置通知,在方法正确执行完毕,返回结果之前执行。

    @After("execution(* springAOP0305.*.*(..))")

    public void after() {

    System.out.println("方法执行结束...");

    }

    }

    1. 添加配置文件的配置,扫描切面类及其他的类到IOC容器中

    xmlns:aop="http://www.springframework.org/schema/aop" 

    xsi:schemaLocation="

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

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

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

    http://www.springframework.org/schema/context/spring-context-4.0.xsd

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

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

    ">

      <!-- 启用注解配置,-->

      <context:annotation-config/>

      <!-- 扫描包中的类,把有注解的类自动创建出对象,存储在IOC容器中  -->

      <context:component-scan base-package="springAOP0305"/>

      <!-- 启动AOP的代理 -->

      <aop:aspectj-autoproxy proxy-target-class="true"/>

    </beans>

    1. 调用被监听的方法

    public static void main(String[] args) {

     ApplicationContext cxt = new ClassPathXmlApplicationContext("config/applicationcontext.xml");

     Calc c = cxt.getBean(Calc.class);

     int result = c.add(100, 50, 20);

     System.out.println("计算结果是:"+result);

    }

    1. 结果

    通知:

    /*

     * execution(public springAOP0305.Calc.*(int, int))切面表达式,指定要监听的方法

     * springAOP0305.Calc.* 是一个通配符,任何方法都行,int,int是方法的参数,必须是两个int型才监听。 可以改成..

     * 表示任意类型,任意数量的参数都行

     */

    // 前置通知,在监听的方法执行前执行..

    @Before("execution(* springAOP0305.*.*(..))")

    public void before(JoinPoint jp) {

    // JoinPoint 是一个连接点对象,封装了方法名称及参数,jp.getSignature().getName()方法名称

    String name = jp.getSignature().getName();

    Object[] args = jp.getArgs(); // 取连接点的参数列表

    System.out.println(name + "方法: 开始执行,参数是:" + Arrays.toString(args));

    }

    // 后置通知,在方法正确执行完毕,返回结果之前执行,不能获取方法的返回结果。

    @After("execution(* springAOP0305.*.*(..))")

    public void after(JoinPoint jp) {

    // JoinPoint 是一个连接点对象,封装了方法名称及参数,jp.getSignature().getName()方法名称

    String name = jp.getSignature().getName();

    Object[] args = jp.getArgs(); // 取连接点的参数列表

    System.out.println(name + "方法: 执行结束了,参数是:" + Arrays.toString(args));

    }

    /*

     * 返回通知,也叫最终通知,在方法返回结果时执行,此时可以获取到方法返回的结果

     * value表示切面表达式,

     * returning:表示方法返回的结果封装的参数名称

     */

    @AfterReturning(value = "execution(* springAOP0305.*.*(..))", returning = "result")

    public void afterReturn(JoinPoint jp, Object result) {

    // JoinPoint 是一个连接点对象,封装了方法名称及参数,jp.getSignature().getName()方法名称

    String name = jp.getSignature().getName();

    Object[] args = jp.getArgs(); // 取连接点的参数列表

    System.out.println(name + "方法: 正确返回结果,参数是:" + Arrays.toString(args)+",计算结果是:"+result);

    }

    //异常通知,也叫例外通知,在方法执行中出现异常才执行,否则不执行,如果有异常,则返回通知不会执行

    @AfterThrowing("execution(* springAOP0305.*.*(..))")

    public void afterThrow() {

    System.out.println("发生错误..");

    }

    当有多个切面的时候,可以给切面执行顺序进行设置,在切面类前添加注解@Order(value=1), 值越小,优先级越高。

    @Aspect

    @Component

    @Order(value=1)  //顺序设置,值小的优先级高

    public class TimeInfo {

    @Before("execution(* springAOP0305.*.*(..))")

    public void befor() {

    System.out.println("时间开始记录..");

    }

    }

    五、XML配置

    在开发中大部分还是采用注解的方式来进行配置,事务管理机制,采用的就是注解配置,简单。

     <!-- 切面类的对象 -->

      <bean id="logInfo" class="springAOP0305.LogInfo"/>

      <bean id="timeInfo" class="springAOP0305.TimeInfo"/>

      

      <!-- AOP配置 -->

      <aop:config>

        <!-- 切入点:切点表达式, -->

        <aop:pointcut expression="execution(* springAOP0305.*.*(..))" id="pcut"/>

        <!-- 切面及通知的配置 order:切面织入的顺序 -->

        <aop:aspect ref="timeInfo" order="1">

          <aop:before method="befor" pointcut-ref="pcut"/>

        </aop:aspect>

        <aop:aspect ref="logInfo" order="2">

          <aop:before method="before" pointcut-ref="pcut"/>

          <aop:after method="after" pointcut-ref="pcut"/>

        </aop:aspect>

      </aop:config>

    六、通配符:

    expression-匹配方法执行的连接点,是Spring最主要的切入点

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

    除了返回类型模式(),名字模式和参数模式以外,其余的都是可选的,*为任意通配符

    expression=execution(* cn.itcast.service..*.*(..))”表示作用在cn.itcast.service包及子包下所有的类的所有方法上

    expression=execution(* cn.itcast.service..*.*(java.lang.String,..))”表示作用在cn.itcast.service包及子包下所有的类的第一个参数为String类型的方法上

    expression=execution(java.lang.String cn.itcast.service..*.*(..))” 表示作用在cn.itcast.service包及子包下所有的类的返回值类型为String的方法上

    expression=execution(!java.lang.String cn.itcast.service..*.*(..))” 表示作用在cn.itcast.service包及子包下所有的类的返回值类型不是String的所有方法上

    expression=execution(* set**(..))” 表示作用在任意以set开始的方法上

    within-限定匹配特定类型的连接点

    expression=winthin(cn.itcast.*)” 表示作用在cn.itcast包及子包下的所有连接点

  • 相关阅读:
    【随手记录】PG数值类型记录
    【SkyWalking】 Can't find service by service instance id from cache, service instance id is:xxx
    【随手记录】定时邮件发送限制 SMTPSendFailedException:557
    【随手记录】IDEA一个工程打开多个项目
    【随手记录】时间格式转换报错:while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ'
    【随手记录】实体类里方法自动执行问题
    【随手记录】IDEA的工具mode切换
    【随手记录】MagicNumber 魔数 在协议里作用
    js singleton
    js 对象的深层嵌套函数对对象属性的访问
  • 原文地址:https://www.cnblogs.com/warriors-curry/p/10489372.html
Copyright © 2011-2022 走看看