zoukankan      html  css  js  c++  java
  • Spring基础3

    一、AOP

      1)AOP简介:

        Aspect Oriented Programming,面向切面编程

        通过预编译方式和动态代理实现程序功能的一种技术,AOP是OOP的延续,是函数式编程的一种衍生范例。利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑之间的耦合度降低,提高程序的可重用性,同时提高开发效率。

        AOP采用横向抽取机制取代了传统纵向继承,不破坏原有的类,生成一个动态代理类,在原有类的基础上进行增强,可以随时添加,随时取消功能。

        Spring中使用的AOP是Aspectj

    二、动态代理

      1)JDK动态代理,依赖接口

          

        

    package com.ual.dao;
    
    public class GoodsDaoImpl implements GoodsDao {
        @Override
        public void save() {
            System.out.println("保存");
        }
    
        @Override
        public void update() {
            System.out.println("更新");
        }
    }
    package com.ual.Proxy;
    
    import com.ual.dao.GoodsDao;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class GoodsJDKProxy {
        public GoodsDao createProxy(GoodsDao goodsDao) {
            GoodsDao goodsDaoProxy = (GoodsDao) Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(),
                    goodsDao.getClass().getInterfaces(), new InvocationHandler() {
                @Override//当调用对象的时候,所有的方法都会来到这里
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                   if("save".equals(method.getName())){
                       System.out.println("保存校验");
                       return method.invoke(goodsDao, args);//返回的代理对象
                   }
                   if("update".equals(method.getName())){
                       System.out.println("更新校验");//方法执行之前,执行
                       GoodsDao goodsDao1 = (GoodsDao)method.invoke(goodsDao, args);//返回的代理对象
                       System.out.println("日志打印");//方法执行之后
                       return  goodsDao1;
                   }
                    return method.invoke(goodsDao, args);//返回的代理对象
                }
            });
            return goodsDaoProxy;//返回一个代理对象,代理对象中的方法执行时,会回调匿名内部类中的Invoke方法。
        }
    }
    package com.ual.test;
    
    import com.ual.Proxy.GoodsJDKProxy;
    import com.ual.dao.GoodsDao;
    import com.ual.dao.GoodsDaoImpl;
    import org.junit.Test;
    
    public class GoodsDaoTest {
        @Test
        public void test() {
            GoodsDao goodsDao = new GoodsDaoImpl();
            /* goodsDao.save();*/
            GoodsJDKProxy goodsJDKProxy = new GoodsJDKProxy();
            GoodsDao proxy = goodsJDKProxy.createProxy(goodsDao);
            proxy.save();
            proxy.update();
        }
    }

      2)cglib动态代理,不需要依赖接口,核心是通过子类继承

      Spring会在jdk与cglib之间进行自动切换,有接口使用jdk,没有接口使用cglib。

      

    三、AOP相关术语

    1)JoinPoint:连接点,可以被拦截的方法,能够(可以)被增强的方法,称为连接点。

    2)Pointcut:切入点,真正被拦截,增强的方法

    3)Advice:通知,增加的内容,通常封装成一个方法,这个方法称之为通知

    4)Introduction:引介,类层面的增强,给原有类添加一些新的属性和方法。在开发中通常给方法加强

    5)Target:被增强的对象

    6)Weaving:织入,将通知应用到目标对象的过程

    7)Proxy:代理对象

    8)Aspect:切面,多个通知和对各切入点的集合

    四、Spring 中AOP的使用

    1)引入Spring基本jar包

    2)引入AOP开发相关jar包

    3)配置文件引入AOP约束

    4)Spring 测试

    引入这个jar包,这样就不用每次都获取工厂

    在测试类上添加

    package com.ual.test;
    
    import com.ual.service.UserService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class UserTest {
        @Autowired
        private UserService userService;
        @Test
        public void test() {
            this.userService.delete();
        }
    }

    5)编写一个切面类

     即里面写入通知

    package com.ual2.demo;
    
    public class Myaspect {
        public void check(){
            System.out.println("校验");
        }
    }

    6)将切面类交给Spring 

    7)配置AOP完成对目标产生代理

        <bean id="myaspect" class="com.ual2.demo.Myaspect"></bean>
        <!--配置AOP-->
        <aop:config>
            <!--切入点:给哪个方法做增强--> 
            <aop:pointcut id="pointDelete" expression="execution(* com.ual.dao.UserDaoImpl.delete(..))"/><!--expression:给哪个类里的哪个方法做增强-->
            <!--切面:增强的功能是什么-->
            <aop:aspect ref="myaspect">
                <aop:before method="check" pointcut-ref="pointDelete"/>
            </aop:aspect>
        </aop:config>
    </beans>

    五、AOP通知类型

    1)前置通知

      在目标方法执行之前执行

    2)后置通知

      在目标方法执行之后执行,可以在通知中可以得到一个目标方法的返回值

    3)环绕通知

    在目标方法执行之前,执行之后操作

    4)异常抛出通知

    在程序出现异常时才会触发

    5)最终通知

    无论代码是否有异常,都会执行

    六、AOP切入点表达式

    基于execution函数完成

    【访问修饰符(可选)】 方法返回值(*代表任意类型)包名.类名.方法名(参数)

    参数:“..”为任意类型;包名.类名+.方法名(参数)当前类和子类该方法都为切入点

       * com.ual..*.*(..):com.ual包以及子包下面的所有类的所有方法都是切入点

    七、AOP中的注解开发

    1)引入jar包

    2)引入配置文件

    3)编写切面类配置

     4)使用注解的AOP对象对目标类进行增强

      1.在配置文件中开启以注解形式进行AOP开发

      2.在切面类上添加注解

      

      3.测试方法

    5)注解AOP通知类型

    1.@Before:前置通知

    2.@AfterReturenning:后置通知

      2.1 没有返回值

      2.2 有返回值

    3.@Around环绕通知 

    4.@AfterThrowing异常抛出通知

      4.1没有获取异常信息

      4.2获取异常信息

    5.@After:最终通知  

    6.同一通知应用多个方法

    也可以用这种方式

    注意:当使用接口时与不使用接口时,Spring内部代理区别:

      1.使用接口,采用jdk动态代理

      2.不使用接口,采用cglib动态代理

  • 相关阅读:
    使用isinstance()函数,判断输入的函数是否为已知的类型。raise() 引发异常。
    maya命令的运用。范例1。#举一反三
    maya中英文切换
    变量和maya命令 #getAttr #setAttr #xform #connectAttr #disconnectAttr
    变量和maya命令 #polySphere命令,创建、查询、编辑。
    PyCharm配置Maya开发环境
    希望与憧憬
    Java RandomAccessFile基本的用法
    Java 文件(File)类
    计算机编码问题
  • 原文地址:https://www.cnblogs.com/UalBlog/p/10663928.html
Copyright © 2011-2022 走看看