zoukankan      html  css  js  c++  java
  • Spring----aop(面向切面编程)

    为什么要使用AOP(面向切面编程)

      在我们整个程序中,通常都有一些公共的代码,反反复复需要我们去写,而aop简单来说就是为我们处理这些公共的代码(专心做事),将之从程序中剥离出来,统一交由spring容器来处理,而我们则只需要将业务逻辑处理好就可以了。

    AOP的原理 

      1.将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决

      2.采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能。

    AOP如何为我们处理这些公共代码呢?

      有以下几种方式:

        1.前置增强(目标方法执行前)

        2.后置增强(目标方法执行后)

        3.环绕增强(相当于前置增强和后置增强一起使用)

        4.异常抛出增强(目标方法抛出异常时执行)

        5.最终增强(相当于try-cache中的finally,如论以上4中增强执行了哪些,最终增强都会执行)

      aop设计单元

        切面(aspect):横切关注点而被模块化的类,称之为切面

        通知(advice):切面要完成的工作,具体指切面类中的某个方法

        连接点(joinpoint):一个应用再执行过程中能被插入切面的一个点

        切点(pointcut):通配表达式,能被匹配一个或则多个连接点

        织入(weaving):将切面应用到目标对象的代理对象的过程

        顾问(adviscor):顾问就是通知,但是顾问又要比通知强大,通知是切面中的所有方法,而顾问则可以指定到某一个方法中

       多说无益,上代码:

     创建业务类

      

     1 public class DoSome {
     2     public void dosome(){
     3         System.out.println("我是service层");
     4     }
     5     //该方法为了对比最终增强和后置增强的效果,还有就是异常抛出增强的效果
     6     public void error(){
     7         int result=5/0;//伪造一个异常
     8         System.out.println("我是异常方法");
     9     }
    10 }

    创建通知类(切面)

     1 public class Advice{
     2     //前置增强
     3     public void before(JoinPoint jp){
     4         System.out.println("我是方法"+jp.getSignature().getName()+"的前置增强!");
     5     }
     6     //后置增强
     7     public void afterReturning(JoinPoint jp,Object obj){
     8         System.out.println("我是方法"+jp.getSignature().getName()+"的后置增强!"+",返回值为"+obj);
     9     }
    10     //环绕增强
    11     public void around(ProceedingJoinPoint jp) throws Throwable {
    12         System.out.println("我是环绕增强中的前置增强!");
    13         Object proceed = jp.proceed();//植入目标方法
    14         System.out.println("我是环绕增强中的后置增强!");
    15     }
    16     //异常抛出增强
    17     public void error(JoinPoint jp,Exception e){
    18         System.out.println("我是异常抛出增强"+",异常为:"+e.getMessage());
    19     }
    20     //最终增强
    21     public void after(JoinPoint jp){
    22         System.out.println("我是最终增强");
    23     }
    24 }

    配置核心配置文件applicationContext.xml

    <!--创建业务类bean对象-->
        <bean id="service" class="com.cn.service.DoSome"></bean>
        <!--创建通知(切面)类的bean对象-->
        <bean id="advice" class="com.cn.advice.Advice"/>
        <!--对业务类进行增强-->
        <aop:config>
            <!--创建切点-->
            <aop:pointcut id="pointcut" expression="execution(public void *(..))"></aop:pointcut>
            <!--植入增强方法-->
            <aop:aspect id="aspect" ref="advice">
                <aop:before method="before" pointcut-ref="pointcut"/>
                <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="obj"/>
                <aop:around method="around" pointcut-ref="pointcut"/>
                <aop:after-throwing method="error" pointcut-ref="pointcut" throwing="e"/>
                <aop:after method="after" pointcut-ref="pointcut"/>
            </aop:aspect>
        </aop:config>

    创建测试类

     1 public class App 
     2 {
     3     public static void main( String[] args )
     4     {
     5         ApplicationContext ac=new ClassPathXmlApplicationContext("/applicationContext.xml");
     6         DoSome bean = ac.getBean(DoSome.class);
     7         //bean.dosome();
     8         bean.error();
     9     }
    10 }

    自行测试,在下就不发截图了

    还有就是需要的pom节点

     1 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
     2         <dependency>
     3             <groupId>org.springframework</groupId>
     4             <artifactId>spring-context</artifactId>
     5             <version>5.1.0.RELEASE</version>
     6         </dependency>
     7         <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
     8         <dependency>
     9             <groupId>org.springframework</groupId>
    10             <artifactId>spring-core</artifactId>
    11             <version>5.1.0.RELEASE</version>
    12         </dependency>
    13         <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
    14         <dependency>
    15             <groupId>org.springframework</groupId>
    16             <artifactId>spring-beans</artifactId>
    17             <version>5.1.0.RELEASE</version>
    18         </dependency>
    19         <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
    20         <dependency>
    21             <groupId>org.springframework</groupId>
    22             <artifactId>spring-expression</artifactId>
    23             <version>5.1.0.RELEASE</version>
    24         </dependency>
    25         <!--以上4个是spring的核心-->
    26         <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    27         <dependency>
    28             <groupId>org.aspectj</groupId>
    29             <artifactId>aspectjweaver</artifactId>
    30             <version>1.9.2</version>
    31         </dependency>
    32         <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
    33         <dependency>
    34             <groupId>org.aspectj</groupId>
    35             <artifactId>aspectjrt</artifactId>
    36             <version>1.9.2</version>
    37         </dependency>

    aspectj是aop的一个工具增强方法中的JoinPoint对象是由aspectj提供

    当然,实现业务增强的方法不光这一种,我们还可以实现接口从写对应的方法

      前置增强(MethodBeforeAdvice)后置增强(AfterReturningAdvice)环绕增强(MethodInterceptor)异常抛出增强(ThrowsAdvice)

      

      

  • 相关阅读:
    Java序列化原理
    分库分表
    数据库索引
    监听TCP端口号:从简单Socket到NIO到Netty
    如何保证缓存与数据库的双写一致性
    代理模式:静态代理、JDK动态代理、Cglib动态代理
    Redis发布订阅(Pub-Sub)模式
    Redis分片机制(Sharding)
    Redis高可用性:主从、哨兵和集群
    Redis简介
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/10423099.html
Copyright © 2011-2022 走看看