大数据正式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结尾即可,中间随便
五大通知
- 环绕通知around
- 前置通知before
- 事务开始
- 后置通知after-returning
- 事务的提交
- 有异常它不执行
- 异常通知after-throwing
- JoinPoint必须放在Throwable前面(Error::0)
- 事务回滚
- 最终通知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>
-