zoukankan      html  css  js  c++  java
  • spring框架学习(四)——注解方式AOP

    注解配置业务类

    使用@Component("s") 注解ProductService 类

    package com.how2java.service;
     
    import org.springframework.stereotype.Component;
     
    @Component("s")
    public class ProductService {
        public void doSomeService(){
            System.out.println("doSomeService");
        }
         
    }

    注解配置切面

    @Aspect 注解表示这是一个切面
    @Component 表示这是一个bean,由Spring进行管理
    @Around(value = "execution(* com.how2java.service.ProductService.*(..))") 表示对com.how2java.service.ProductService 这个类中的所有方法进行切面操作

    package com.how2java.aspect;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
     
    @Aspect
    @Component
    public class LoggerAspect {
         
        @Around(value = "execution(* com.how2java.service.ProductService.*(..))")
        public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("start log:" + joinPoint.getSignature().getName());
            Object object = joinPoint.proceed();
            System.out.println("end log:" + joinPoint.getSignature().getName());
            return object;
        }
    }

    springconfig.xml

    去掉原有信息,添加如下3行

    <context:component-scan base-package="com.how2java.aspect"/>
    <context:component-scan base-package="com.how2java.service"/>

    扫描包com.how2java.aspect和com.how2java.service,定位业务类和切面类

    <aop:aspectj-autoproxy/>

    找到被注解了的切面类,进行切面配置

    <?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"> <context:component-scan base-package="com.how2java.aspect"/> <context:component-scan base-package="com.how2java.service"/> <aop:aspectj-autoproxy/> </beans>

    测试运行

    package com.how2java.test;
      
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    import com.how2java.service.ProductService;
     
    public class TestSpring {
      
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    new String[] { "springconfig.xml" });
            ProductService s = (ProductService) context.getBean("s");
            s.doSomeService();
        }
    }

    ---------------------------------------------------------------------------------------------------------------

    ---------------------------------------------------------------------------------------------------------------

     在how2j 网站学习spring框架时,发现有网友留了一些问题,这里我们拿出来分享一下

    1. 为什么用注解方式跑程序比用xml配置要慢?

    xml文件的形式,系统只需要解析xml文件中的内容,你需要自己去管理xml文件。而注解最终要调用反射,反射很耗时间的,换来的是不需要去管理xml文件,二者各有优缺点,看情况选择合适的方式。

    2. 假如一个业务有两个切面如何区分先后顺序?比较重要

    使用xml配置的时候,在定义切面时,如果通知的类型相同,可以加上order定义多个切面的执行顺序,这里有两种情况:

    <aop:aspect id="logAspect2" ref="loggerAspect2" order="1">
         <aop:before pointcut-ref="loggerCutpoint" method="log"/>
    </aop:aspect>
    
    <aop:aspect id="logAspect3" ref="loggerAspect3" order="2">
         <aop:before pointcut-ref="loggerCutpoint" method="log"/>
    </aop:aspect>    

    上面的通知类型都是before,order的数值越小越先执行!!!

    <aop:aspect id="logAspect2" ref="loggerAspect2" order="1">
         <aop:after pointcut-ref="loggerCutpoint" method="log"/>
    </aop:aspect>
    
    <aop:aspect id="logAspect3" ref="loggerAspect3" order="2">
         <aop:after pointcut-ref="loggerCutpoint" method="log"/>
    </aop:aspect>    

    上面的通知类型都是after,order的数值越大越先执行!!!

    在定义切面时,如果通知的类型不同,则无论怎样定义order都无法决定多个切面的执行顺序

    <!--该切面order="1",但通知是after类型-->
    <aop:aspect id="logAspect2" ref="loggerAspect2" order="1"> <aop:after pointcut-ref="loggerCutpoint" method="log"/> </aop:aspect>
    <!--该切面order="2",但通知是before类型-->
    <aop:aspect id="logAspect3" ref="loggerAspect3" order="2">
       <aop:before pointcut-ref="loggerCutpoint" method="log"/>
    </aop:aspect>

    这种情况切面的执行顺序是按通知的类型决定的!!!

    用注解的方式定义切面,执行的先后顺序其原理和xml配置一样。

    3. 如何把一个切面织入两个不同的业务类中?

    可在切面中加入

    @Around(value = "execution(* com.java.ProductService.*(..)) || execution(* com.java.service.ProductService2.*(..))")

    如果分开写,会报错,例如 

    @Around(value = "execution(* com.java.ProductService.*(..))"
    @Around(value = "execution(* com.java.ProductService2.*(..))"    

      

  • 相关阅读:
    Python 之 面向对象(一)
    Python 之 基础知识(五)
    javaweb 之 代理模式
    Python 之 基础知识(四)
    Python 之 基础知识(三)
    如何在非 sudo 用户下运行 docker 命令?
    Leetcode 55
    Leetcode 11
    Leetcode 466
    几个内存操作函数使用
  • 原文地址:https://www.cnblogs.com/churujianghudezai/p/11812377.html
Copyright © 2011-2022 走看看