zoukankan      html  css  js  c++  java
  • Spring-Aop

    一.AOP(Aspect Oriented Programing)面向切面编程

    AOP的终极目标:让我们可以专心做事

    下面通过一个例子来介绍AOP的具体使用

    案例的要求:使用AOP实现日志记录系统 ,  核心模块  和    增强  单独  开发  ,运行时再组装

    首先定义接口和方法

    接口和实现类中的代码,我放在一起了,应该比较简单

    复制代码
    package demo04.dao;
    
    /**
     * Created by mycom on 2018/3/5.
     */
    public interface IHelloDao {
        public void doSome();
    }


    package demo04.dao;

    /**
    * Created by mycom on 2018/3/5.
    */
    public class HelloDaoImpl implements IHelloDao {
    public void doSome() {
    System.out.println("已经成功加入到DB中了");
    }
    }


    package demo04.service;

    /**
    * Created by mycom on 2018/3/5.
    */
    public interface IHelloService {
    public void doSome();
    }


    package demo04.service;

    import demo04.dao.IHelloDao;

    /**
    * Created by mycom on 2018/3/5.
    */
    public class HelloServiceImpl implements IHelloService {
    //创建一个Dao的对象
    IHelloDao dao;

    public IHelloDao getDao() {
    return dao;
    }

    public void setDao(IHelloDao dao) {
    this.dao = dao;
    }

    public void doSome() {
    dao.doSome();
    }
    }


    复制代码

    同样在resources下面也要有一个xml文件----applicationContext.xml

    复制代码
    <!--返回的类型只能是实现类-->  这里需要注意一下  class的值只能是实现类的包
        <bean id="dao" class="demo04.dao.HelloDaoImpl">
        </bean>
    
        <bean id="service" class="demo04.service.HelloServiceImpl">
            <property name="dao" ref="dao"></property>
        </bean>
    复制代码

    然后编写测试类进行测试

    复制代码
    @Test
        public void t1(){
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAop.xml");
            //这里的返回值只能是接口
            IHelloService service =(IHelloService) context.getBean("service");
            service.doSome();
        }
    复制代码

    运行的结果

    现在我们要在这句话出现之前,先记录一下日志,出现之后,再出现一句话

    首先要创建一个新的包AOP包,并且在包下面写两个类

    LoggerAfter是后置增强

    LoggerBefore是前置增强

    这两个类中的代码如下

    复制代码
    package demo04.aop;
    
    import org.springframework.aop.AfterReturningAdvice;
    
    import java.lang.reflect.Method;
    
    /**
     * Created by mycom on 2018/3/5.
     */
    public class LoggerAfter implements AfterReturningAdvice {
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("=======after");
        }
    }
    复制代码
    复制代码
    package demo04.aop;
    
    import org.springframework.aop.MethodBeforeAdvice;
    
    import java.lang.reflect.Method;
    
    /**
     * Created by mycom on 2018/3/5.
     */
    public class LoggerBefore implements MethodBeforeAdvice {
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("日志记录");
        }
    }
    复制代码

    在xml中配置,在配置xml是要给AOP添加一个约束

    复制代码
    <?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"
           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">
    复制代码
    复制代码
    <bean id="service" class="demo04.service.HelloServiceImpl">
            <property name="dao" ref="dao"></property>
        </bean>
        <!--前置-->
        <bean id="beforeAdvice" class="demo04.aop.LoggerBefore">
        </bean>
        <!--后置-->
        <bean id="afterAdvice" class="demo04.aop.LoggerAfter">
        </bean>
        <!--配置aop-->
        <aop:config>
            <!--切点-->
            <aop:pointcut id="mypoint" expression="execution(public void demo04.service.HelloServiceImpl.doSome())"></aop:pointcut>
            <!--<aop:pointcut id="mypoint" expression="execution(* *..service.*.*(..))"></aop:pointcut>-->
            <!--advice-ref:做什么样的配置,是前置还是后置
            pointcut-ref:锁定什么样的方法规则,那个方法需要被锁定
            -->
            <aop:advisor advice-ref="beforeAdvice" pointcut-ref="mypoint"></aop:advisor>
            <aop:advisor advice-ref="afterAdvice" pointcut-ref="mypoint"></aop:advisor>
        </aop:config>
    复制代码

    测试类

    复制代码
    import demo04.service.HelloServiceImpl;
    import demo04.service.IHelloService;
    import demo05.MyCollection;
    import demo05.Student;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * Created by mycom on 2018/3/3.
     */
    public class Test20180305 {
        @Test
        public void t1(){
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAop.xml");
            //这里的返回值只能是接口
            IHelloService service =(IHelloService) context.getBean("service");
            service.doSome();
    
        }
    
    
    }
    复制代码

    在这里和要介绍两个单词的意思

      advice :通知
      advisor:顾问

    顾问可以包装通知

    execution(【modifiers-pattern?】 访问修饰符
    ret-type-pattern 返回值类型
    【declaring-type-pattern?】 全限定性类名
    name-pattern(param-pattern) 方法名(参数名) 包名.类型名.方法名
    【throws-pattern?】) 抛出异常类型
    public void doLog(String log){

    }

    方法签名

    切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。
    注意:表达式中加[]的部分表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:
    符号 意义
    * 0至多个任意字符
    .. 用在方法参数中,表示任意多个参数
    用在包名后,表示当前包及其子包路径
    + 用在类名后,表示当前类及其子类
    用在接口后,表示当前接口及其实现类
    execution(public * *(..)) 指定切入点为:任意公共方法
    execution(* set*(..)) 指定切入点为:任何一个以"set"开始的方法

  • 相关阅读:
    关于订单创建的service层
    使用注解@RestController返回json类型的数据
    关于lombok包(可使编程便捷)的一些使用
    Django学习笔记一十三——ORM查询练习
    Django学习笔记一十二——建立多对多结构表的三种方式
    Django学习笔记一十一——ORM学习三
    Django学习笔记一十——Django项目在python脚本中的调用
    Django学习笔记〇九——路由系统
    Django学习笔记〇八——模板语言系统
    Django学习笔记〇七——MCV和MTV框架介绍
  • 原文地址:https://www.cnblogs.com/buai/p/8513052.html
Copyright © 2011-2022 走看看