大数据正式30

大数据正式30

课程回顾

  • AOP
    • AOP概念:面向切面编程
    • 连接点:目标方法
    • 切入点:规则(Expression),满足表达式的方法才称之为切入点
    • 切面:类 (事务、权限、异常)
    • 通知:额外的方法

今天:表达式

  • 切入点的Execution表达式

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?
     name-pattern(param-pattern) throws-pattern?)
    
modifiers-pattern ? ret-type-pattern declaring-type-pattern? name-pattern (param-pattern) throws-pattern ?
修饰符
(可有可无)
返回值 全类名
(可有可无)
方法名 参数列表 抛出异常
(可有可无)
    • 任意公共方法的执行:

      execution(public * *(..))
      
    • 任何一个名字以“set”开始的方法的执行:

      execution(* set*(..))
      
    • AccountService接口定义的任意方法的执行:

      execution(* com.xyz.service.AccountService.*(..))
      
    • 在service包中定义的任意方法的执行:

      execution(* com.xyz.service.*.*(..))
      
    • 在service包或其子包中定义的任意方法的执行:

      execution(* com.xyz.service..*.*(..))
      
  • 注:xxx..yyy xxx开头yyy结尾即可,中间随便

五大通知

  1. 环绕通知around
  2. 前置通知before
    1. 事务开始
  3. 后置通知after-returning
    1. 事务的提交
    2. 有异常它不执行
  4. 异常通知after-throwing
    1. JoinPoint必须放在Throwable前面(Error::0)
    2. 事务回滚
  5. 最终通知after

环绕通知的嵌套

例子

  • 正常的通知(关键代码)

    • 切面类

      package com.peng.aspect;
      
      import org.aspectj.lang.JoinPoint;
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Component;
      
      import com.peng.manager.Manager;
      
      /**
       * 切面
       * 
       * @author Administrator
       * 
       */
      @Component(value = "txaspect")
      public class TxAspect {
          @Autowired
          @Qualifier(value = "manager")
          Manager manager;
      
          // 前置通知
          public void before(JoinPoint jp) {
              System.out.println("前置通知类:" + jp.getTarget().getClass());
              System.out.println("前置通知方法:" + jp.getSignature().getName());
          }
      
          // 环绕通知
          public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
              manager.start();// 开始事务
              // 执行目标方法
              System.out.println("asdfghj");
              Object result = joinPoint.proceed();
              System.out.println("asdfghj");
              manager.commit();// 提交事务
              return result;
          }
      
          // 后置通知
          public void after_returning(JoinPoint jp) {
              System.out.println("后置通知类:" + jp.getTarget().getClass());
              System.out.println("后置通知方法:" + jp.getSignature().getName());
          }
      
          // 异常通知
          public void throwable(JoinPoint jp, Throwable tw) {
              System.out.println("异常通知类:" + jp.getTarget().getClass());
              System.out.println("异常通知方法:" + jp.getSignature().getName());
              System.out.println("异常类型:" + tw.getClass());
              System.out.println("异常信息:" + tw.getMessage());
          }
      
          // 最终通知
          public void after(JoinPoint jp) {
              System.out.println("最终通知类:" + jp.getTarget().getClass());
              System.out.println("最终通知方法:" + jp.getSignature().getName());
          }
      
      }
      
    • service层的业务逻辑

      package com.peng.service;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Service;
      
      import com.peng.dao.PersonDao;
      import com.peng.pojo.Person;
      
      @Service(value = "serviceImpl")
      public class PersonServiceImpl implements PersonService {
          @Autowired
          @Qualifier(value = "personDao")
          private PersonDao dao;
      
          @Override
          public void savePerson(Person p) {
              if (null != dao) {
                  // int a = 1 / 0;//异常通知实验
                  dao.savePerson(p);
              }
          }
      }
      
    • 配置文件

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
          <!-- 开启包扫描 -->
          <context:component-scan base-package="com.peng"></context:component-scan>
          <!-- 开启注解开关 -->
          <context:annotation-config></context:annotation-config>
          <aop:config>
              <!-- 切入点(规则:其实就是个路径) -->
              <aop:pointcut expression="execution(* com.peng.service.*.*(..))"
                  id="pc" />
              <!-- 配置切面 -->
              <aop:aspect ref="txaspect">
                  <!-- 方法 通知 -->
                  <aop:before method="before" pointcut-ref="pc" />
                  <aop:around method="around" pointcut-ref="pc" />
                  <aop:after-returning method="after_returning"
                      pointcut-ref="pc" />
                  <aop:after-throwing method="throwable" throwing="tw"
                      pointcut-ref="pc" />
                  <aop:after method="after" pointcut-ref="pc" />
              </aop:aspect>
          </aop:config>
      </beans>
      
    • 执行效果

      十二月 22, 2017 10:59:26 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
      INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@873b9f: startup date [Fri Dec 22 10:59:26 CST 2017]; root of context hierarchy
      十二月 22, 2017 10:59:26 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
      INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
      十二月 22, 2017 10:59:28 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
      INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9ea162: defining beans [txaspect,personDao,manager,person,serviceImpl,serviceImpl2,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,pc,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
      =================懒加载在此之后=================
      ============构造函数===========
      =====Person=====init==========
      前置通知类:class com.peng.service.PersonServiceImpl
      前置通知方法:savePerson
      start................
      asdfghj
      保存了~~名称:张三,年龄:12
      asdfghj
      commit................
      后置通知类:class com.peng.service.PersonServiceImpl
      后置通知方法:savePerson
      最终通知类:class com.peng.service.PersonServiceImpl
      最终通知方法:savePerson
      十二月 22, 2017 10:59:28 上午 org.springframework.context.support.AbstractApplicationContext doClose
      INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@873b9f: startup date [Fri Dec 22 10:59:26 CST 2017]; root of context hierarchy
      十二月 22, 2017 10:59:28 上午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
      INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9ea162: defining beans [txaspect,personDao,manager,person,serviceImpl,serviceImpl2,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,pc,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
      =====Person=====destory==========
      
  • 有异常的通知

    • 切面类

      package com.peng.aspect;
      
      import org.aspectj.lang.JoinPoint;
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Component;
      
      import com.peng.manager.Manager;
      
      /**
       * 切面
       * 
       * @author Administrator
       * 
       */
      @Component(value = "txaspect")
      public class TxAspect {
          @Autowired
          @Qualifier(value = "manager")
          Manager manager;
      
          // 前置通知
          public void before(JoinPoint jp) {
              System.out.println("前置通知类:" + jp.getTarget().getClass());
              System.out.println("前置通知方法:" + jp.getSignature().getName());
          }
      
          // 环绕通知
          public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
              manager.start();// 开始事务
              // 执行目标方法
              System.out.println("asdfghj");
              Object result = joinPoint.proceed();
              System.out.println("asdfghj");
              manager.commit();// 提交事务
              return result;
          }
      
          // 后置通知
          public void after_returning(JoinPoint jp) {
              System.out.println("后置通知类:" + jp.getTarget().getClass());
              System.out.println("后置通知方法:" + jp.getSignature().getName());
          }
      
          // 异常通知
          public void throwable(JoinPoint jp, Throwable tw) {
              System.out.println("异常通知类:" + jp.getTarget().getClass());
              System.out.println("异常通知方法:" + jp.getSignature().getName());
              System.out.println("异常类型:" + tw.getClass());
              System.out.println("异常信息:" + tw.getMessage());
          }
      
          // 最终通知
          public void after(JoinPoint jp) {
              System.out.println("最终通知类:" + jp.getTarget().getClass());
              System.out.println("最终通知方法:" + jp.getSignature().getName());
          }
      
      }
      
    • service层的业务逻辑

      package com.peng.service;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Service;
      
      import com.peng.dao.PersonDao;
      import com.peng.pojo.Person;
      
      @Service(value = "serviceImpl")
      public class PersonServiceImpl implements PersonService {
          @Autowired
          @Qualifier(value = "personDao")
          private PersonDao dao;
      
          @Override
          public void savePerson(Person p) {
              if (null != dao) {
                  int a = 1 / 0;//异常通知实验
                  dao.savePerson(p);
              }
          }
      }
      
    • 配置文件

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
          <!-- 开启包扫描 -->
          <context:component-scan base-package="com.peng"></context:component-scan>
          <!-- 开启注解开关 -->
          <context:annotation-config></context:annotation-config>
          <aop:config>
              <!-- 切入点(规则:其实就是个路径) -->
              <aop:pointcut expression="execution(* com.peng.service.*.*(..))"
                  id="pc" />
              <!-- 配置切面 -->
              <aop:aspect ref="txaspect">
                  <!-- 方法 通知 -->
                  <aop:before method="before" pointcut-ref="pc" />
                  <aop:around method="around" pointcut-ref="pc" />
                  <aop:after-returning method="after_returning"
                      pointcut-ref="pc" />
                  <aop:after-throwing method="throwable" throwing="tw"
                      pointcut-ref="pc" />
                  <aop:after method="after" pointcut-ref="pc" />
              </aop:aspect>
          </aop:config>
      </beans>
      
    • 执行效果

      十二月 22, 2017 11:01:30 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
      INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@873b9f: startup date [Fri Dec 22 11:01:30 CST 2017]; root of context hierarchy
      十二月 22, 2017 11:01:30 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
      INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
      十二月 22, 2017 11:01:31 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
      INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7561aa: defining beans [txaspect,personDao,manager,person,serviceImpl,serviceImpl2,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,pc,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
      =================懒加载在此之后=================
      ============构造函数===========
      =====Person=====init==========
      前置通知类:class com.peng.service.PersonServiceImpl
      前置通知方法:savePerson
      start................
      asdfghj
      异常通知类:class com.peng.service.PersonServiceImpl
      异常通知方法:savePerson
      异常类型:class java.lang.ArithmeticException
      异常信息:/ by zero
      最终通知类:class com.peng.service.PersonServiceImpl
      最终通知方法:savePerson
      

AOP的注解形式

  • 切面类

    package com.peng.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
    
    import com.peng.manager.Manager;
    
    /**
     * 切面
     * 
     * @author Administrator
     * 
     */
    @Component
    @Aspect
    public class TxAspect {
        @Autowired
        @Qualifier(value = "manager")
        Manager manager;
    
        // /创建一个切入点表达式的引用
        @Pointcut("within(com.peng.service.*)")
        public void pc() {
        }
    
        // 此方法当代理对象执行方法的时候去执行---------连接点
        @Around(value = "pc()")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            manager.start();// 开始事务
            // 执行目标方法
            Object result = joinPoint.proceed();
            manager.commit();// 提交事务
            return result;
        }
    
    }
    
  • 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
        <!-- 开启包扫描 -->
        <context:component-scan base-package="com.peng"></context:component-scan>
        <!-- 开启注解开关 -->
        <context:annotation-config>
        </context:annotation-config>
        <!-- aop注解开关 -->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    </beans>
    

自定义注解

  • 方便自己来更好的控制
  • 步骤
    • 声明注解
    • 使用注解
    • 判断注解
  • 使用前景
    • 事务
    • 安全
    • 。。。
  • 例子

    • 自定义注解

      package com.peng.create;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      @Target(ElementType.METHOD)
      // 注解类型--方法
      @Retention(RetentionPolicy.RUNTIME)
      // 时间点--运行时
      public @interface Transication {
          // 参数声明
          String value() default "small";// 有default可以不用写,没有default必须写--------------具体用到的注解中
      }
      
    • service层

      package com.peng.service;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Service;
      
      import com.peng.create.Transication;
      import com.peng.dao.PersonDao;
      import com.peng.pojo.Person;
      
      @Service(value = "serviceImpl")
      public class PersonServiceImpl implements PersonService {
          @Autowired
          @Qualifier(value = "personDao")
          private PersonDao dao;
      
          @Override
          @Transication(value = "save")
          public void savePerson(Person p) {
              if (null != dao) {
                  dao.savePerson(p);
              }
          }
      
      }
      
    • 切面

      package com.peng.aspect;
      
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.Around;
      import org.aspectj.lang.annotation.Aspect;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.stereotype.Component;
      
      import com.peng.create.Transication;
      import com.peng.manager.Manager;
      
      /**
       * 切面
       * 
       * @author Administrator
       * 
       */
      @Component
      @Aspect
      public class TxAspect {
          @Autowired
          @Qualifier(value = "manager")
          Manager manager;
      
          // /创建一个切入点表达式的引用
      
          // 此方法当代理对象执行方法的时候去执行---------连接点
          @Around(value = "within(com.peng.service.*) && @annotation(ts)")
          public Object around(ProceedingJoinPoint joinPoint, Transication ts)
                  throws Throwable {
      
              System.out.println(ts.value());
              // TODO权限
              // 获取用户的权限
              // 获取注解中的权限--权限类(静态list)
              // 判断当前用户中是否有该权限,并执行相应的操作
      
              manager.start();// 开始事务
              // 执行目标方法
              Object result = joinPoint.proceed();
              manager.commit();// 提交事务
              return result;
          }
      
      }
      
    • 配置文件

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
          <!-- 开启包扫描 -->
          <context:component-scan base-package="com.peng"></context:component-scan>
          <!-- 开启注解开关 -->
          <context:annotation-config>
          </context:annotation-config>
          <!-- aop注解开关 -->
          <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
      </beans>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值