大数据WEB阶段Spring框架 AOP面向切面编程(二)
来源:互联网 发布:python基本数据类型 编辑:程序博客网 时间:2024/06/05 06:00
Spring AOP面向切面编程(二)
一、切入点的execution表达式
execution的表达形式: execution(修饰符? 返回值类型 所在包类? 方法名(参数列表) 异常?)
- ?表示可有可无
execution(public * *(..))
工程中所有的public方法
execution(* set*(..))
工程中所有方法名以set开头的方法
execution(* com.xyz.service.AccountService.*(..))
com.xyz.service.AccountService类下面的所有方法
execution(* com.xyz.service..(..))
com.xyz.service包下所有类的所有方法
execution(* com.xyz.service...(..))
com.xyz.service包下及其子包下所有类的所有方法
execution(* com.xyz..service..(..))
报名以com.xyz开头的所有子包一直子到service下的所有类的所有方法
举例:com.xyz.a.b.service com.xyz.a.service com.xyz.a.b.c.service 会满足上面的条件- ?表示可有可无
二、五大通知的具体实现
- 环绕通知 around
- 5个中最强大的通知,唯一一个能在通知中控制目标方法是否执行的通知
- 前置通知
- 配置文件配置
- 后置通知
- 配置文件配置
- 异常通知
- 异常通知可以控制出现异常后事务回滚 , 和记录日志
- 配置文件配置
- 注意: JoinPoint参数必须放在第一位
- 最终通知
- 不管是么情况都会执行
三、AOP注解
- 在配置文件中把aop注解开关打开
- 通过注解配置切面类
- 通过注解配置通知方法
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 最终通知
四、通过注解生成切入点表达式的引用
- 创建一个空方法
- 使用@Pointcut注解生成一个切入点的引用
- 使用
五、环绕嵌套问题
六、自定义注解
- 声明一个注解
- 使用
- 判断是否有注解
七、各种示例
异常
代码结构如图所示 PersonServlet PersonService PersonDao用异常通知捕获servlet的所有的方法抛出的异常:目标对象所在的类 cn.tedu.big1601.servlet.PersonServlet抛出异常所在的方法 save()抛出异常的名称 XxxException异常信息 message意义:异常处理类和业务逻辑类完全松耦合。时刻捕获生产生产环境中所有的错误,实时监控该系统,异常收集。@Component@Aspectpublic class ExceptionAspect { @AfterThrowing(value = "execution(* com.tj..*(..))" ,throwing = "throwable" ) public void after(JoinPoint jp , Throwable throwable){ System.out.println("异常发生在:"+jp.getTarget().getClass()); System.out.println(jp.getSignature().getName()+"()发生了异常!"); System.out.println("发生异常类型:"+throwable.getClass()); System.out.println("异常信息:"+throwable.getMessage()); }}
统计方法执行时间
计算servlet的各个类的各个方法的执行时间1.类的名称2.方法的名称 3.执行的时间控制台输出意义:用来监控程序的性能问题 @Component@Aspectpublic class RuntimeAspect { @Around("execution(* com.tj..*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable{ Long begin = System.currentTimeMillis(); Object result = pjp.proceed(); Long end = System.currentTimeMillis(); System.out.println(pjp.getTarget().getClass()+"类"+pjp.getSignature().getName()+"方法执行了"+ (end - begin)+"毫秒!"); return result; }}
事务控制
当方法上有事务的注解,该方法就有事务。 写一个切面来完成事务控制类 public class TxManage { /** * 开启事务 * */ public static void stattx(){ System.out.println("开启了事务"); } /** * 提交事务 * */ public static void commitTx(){ System.out.println("提交事务"); } /** * 回滚事务 * */ public static void rollback(){ System.out.println("事务回滚"); }}自定义事务注解@Target(value = { ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface TxAnnotation { String value() default "";}给需要事务控制的地方添加注解@Componentpublic class PersonServiceImpl implements PersonService{ @Autowired private PersonDao dao; @TxAnnotation @Cacheable("add") @Override public void savePerson(Person person) { dao.savePerson(person); } @TxAnnotation @Cacheable("get") @Override public Person getPerson(int id) { Person person = dao.getPerson(id); return person; } @TxAnnotation @Cacheable("del") @Override public void delPerson(int id) { dao.delPerson(id); }}事务控制切面@Component@Aspectpublic class TxAspect { @Around(value = "execution(* com.tj..*(..)) && @annotation(ann)") public Object around(ProceedingJoinPoint pjp ,TxAnnotation ann ) throws Throwable{ Object result = null; try{ TxManage.stattx(); result = pjp.proceed(); TxManage.commitTx(); }catch(Exception e){ TxManage.rollback(); } return result; }}
权限控制
说明:每个方法上添加能够执行该方法的注解@PrivilegeInfo 并且要指明PrivilegeInfo(name=”add”) 那么将来这个方法只能执行还有add权限的方法自定义权限控制注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface PrivilegeInfo { String value() ;}给需要控制权限的地方添加权限控制注解@Componentpublic class PersonServlet { @Autowired private PersonService ps; /** * 保存用户信息 * */ @PrivilegeInfo("add") public void savePerson(Person person){// int i = 1/0; ps.savePerson(person); } /** * 获取用户信息 * */ @PrivilegeInfo("get") public Person getPerson(int id){ Person person = ps.getPerson(id); return person ; } /** * 删除用户信息 * */ @PrivilegeInfo("del") public void delPerson(int id ){ ps.delPerson(id); }}权限控制切面类@Component@Aspectpublic class PrivilegInfoAspect { //当前用户的权限 List<String> list =Arrays.asList("add" , "get"); @Around("execution(* com.tj..*(..)) && @annotation(ann)") public Object around(ProceedingJoinPoint pjp , PrivilegeInfo ann) throws Throwable{ String value = ann.value(); Object result = null; if(list.contains(value)){ System.out.println("尊敬的飞秋会员你好!"); result = pjp.proceed(); }else{ System.out.println("你没有这个权限 ,滚"); } return result; }}
数据缓存
缓存需求:1.savePerson的时候需要往数据库里保存一份然后再往内存(Map)中保存一份 2.getPerson的时候先从Map中获取 如果有则返回则不用执行目标方法,如果内存中没有则执行目标方法从数据库取3.如果第一次调用getPerson内存中没有的话 执行目标方法从数据库取 取出来后同时把获取到的Person对象保存到内存中,以便后续获取时直接从内存中取自定义 缓存控制注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Cacheable { String value();}给需要缓存的地方添加注解@Componentpublic class PersonServiceImpl implements PersonService{ @Autowired private PersonDao dao; @TxAnnotation @Cacheable("add") @Override public void savePerson(Person person) { dao.savePerson(person); } @TxAnnotation @Cacheable("get") @Override public Person getPerson(int id) { Person person = dao.getPerson(id); return person; } @TxAnnotation @Cacheable("del") @Override public void delPerson(int id) { dao.delPerson(id); }}缓存控制切面类@Component@Aspectpublic class CacheableAspect { //缓存 Map<Integer , Person> map = new HashMap<Integer,Person>(); @Around("execution(* com.tj..*(..))&& @annotation(ann)") public Object befer(ProceedingJoinPoint jp , Cacheable ann) throws Throwable{ Object result = null; String v = ann.value(); if(v.equals("add")){ Person person = (Person) jp.getArgs()[0]; int id = person.getId(); if(map.containsKey(id)){ System.out.println("该用户已存在"); }else{ System.out.println("存入 缓存"); map.put(id, person); result = jp.proceed(); } }else if(v.equals("get")){ int id = (Integer) jp.getArgs()[0]; if(map.containsKey(id)){ System.out.println("从缓存中获取"); result = map.get(id); }else{ result = jp.proceed(); Person person = (Person) result; map.put(person.getId(), person); } } return result; } }
阅读全文
0 0
- 大数据WEB阶段Spring框架 AOP面向切面编程(二)
- 大数据WEB阶段Spring框架 AOP面向切面编程(一)
- Spring框架(二)--AOP面向切面编程
- Spring框架之AOP面向切面编程
- 【spring框架】(三)面向切面编程(AOP)
- SSM框架 之 Spring-AOP(面向切面编程)
- SSM框架 之 Spring-AOP(面向切面编程)
- spring学习(二)AOP面向切面编程
- Spring配置过程 (二)面向切面编程AOP
- Spring AOP 面向切面编程(一)
- Spring实践:面向切面编程(AOP)
- Spring 的面向切面编程(AOP)
- Spring 面向切面(AOP)编程,注解
- Spring面向切面编程AOP(around)
- Spring AOP(面向切面编程)
- Spring核心AOP(面向切面编程)
- Spring---面向切面编程(aop)实例
- Spring之AOP(面向切面编程)
- C#创建,发布WebService详细教程
- 一步一步分析讲解神经网络基础-gradient descent algorithm
- 关于一个exe调用另外一个exe如何调试
- 雇员管理系统-SSH版(三)
- 只有2~3年左右的开发经验,为什么年薪就可以达到50万+?
- 大数据WEB阶段Spring框架 AOP面向切面编程(二)
- Activity生命周期和启动模式
- UML总结(一)----面向对象技术
- 大数据WEB阶段Spring框架 AOP面向切面编程(一)
- 一些好东西
- 数据结构学期大总结
- Python的hasattr() getattr() setattr() 函数使用方法详解
- 雇员管理系统-SSH版(四)
- 是那行代码,彻底改变了程序员的世界?