上一篇所讲到的Advice,经过ProxyFactoryBean织入到Bean中,实际上是织入到Bean的联接点上,这显然不是我们想看到的,因为并不是所有方法都需要同样的公用代码。spring提供了切点(Pointcut)的概念,指真正需要织入Advice的联接点,并且提供了专门的类org.springframework.aop.support.NameMatchMethodPointcutAdvisor把Advice和Pointcut结合成一个整体,叫切面(Advisor),这样对Bean的方法就可以有选择的进行处理。因此,Advice只有切面化之后才能显现出AOP的巨大优势。
比如,我们对Dao类进行添加事务的处理,显然只有增,删,改才需要,而查询方法就不再需要。
Dao类:
public class StudentDaoImpl implements StudentDao {

@Override
  public void delete(Integer id) {//事务处理已经被提取出去了
    Student stu=getStudentById(id);
    Session session=HibernateUtil.getCurrentSession();
    session.delete(stu);
  }

@Override
  public Student getStudentById(Integer id) {//查询不需要事务
    Session session=HibernateUtil.openSession();
    Student stu=(Student)session.get(Student.class, id);
    return stu;
  }

@SuppressWarnings("unchecked")
  @Override
  public List<Student> getStudents() {//查询不需要事务
    Session session=HibernateUtil.openSession();
    String hql="from Student";
    List<Student> stus=session.createQuery(hql).list();
    return stus;
  }

@Override
  public void insert(Student stu) {//事务处理已经被提取出去了
    Session session=HibernateUtil.getCurrentSession();
    session.save(stu);
  }

@Override
  public void modify(Student stu) {//事务处理已经被提取出去了
    Session session=HibernateUtil.getCurrentSession();
    session.saveOrUpdate(stu);
  }
}

Advice:
public class TransactionAdvice implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    try{
    Session session=HibernateUtil.getCurrentSession();
    Transaction trans=session.beginTransaction();
    trans.begin();
    System.out.println("====begin transaction====");
    Object ret=invocation.proceed();
    trans.commit();
    System.out.println("====commit transaction====");
    return ret;
    }catch(Exception e){
      HibernateUtil.getCurrentSession().getTransaction().rollback() ;
      System.out.println( "**** rollback transaction ****") ;
      throw e ;
    }
  }
}
配置文件:
<beans>
  <bean id="targetDao" class="com.yangfei.spring.advisor.dao.StudentDaoImpl"></bean>
  <bean id="transAdvice" class="com.yangfei.spring.advisor.advice.TransactionAdvice"></bean>
  <bean id="transAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice">
      <ref local="transAdvice"/>
    </property>
    <property name="mappedNames">
      <list>
        <value>insert</value>
        <value>delete</value>
        <value>modify</value>
      </list>
    </property>
  </bean>
  <bean id="dao" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
      <ref bean="targetDao"/>
    </property>
    <property name="interceptorNames">
      <list>
        <value>transAdvisor</value>
      </list>
    </property>
      <property name="interfaces">
    <list>
      <value>com.yangfei.spring.advisor.dao.StudentDao</value>
    </list>
  </property>
  </bean>
</beans>
测试:
public static void main(String[] args) {
    ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
    StudentDao dao=(StudentDao)ctx.getBean("dao");
    //查
    Student stu=dao.getStudentById(2);
    System.out.println(stu);
    
    List<Student> stus=dao.getStudents();
    for(Student s:stus){
      System.out.println(s);
    }
    /*
    dao.delete(4);
    
    Student s=new Student();
    s.setName("wangwu");
    s.setBirthday(new Date());
    dao.insert(s);*/
    
    Student s=new Student();
    s.setId(4);
    s.setName("zhaoliu");
    s.setBirthday(new Date());
    dao.modify(s);
运行结果:
Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.birthday as birthday0_0_ from spring_student student0_ where student0_.id=?
Student: zhangsan
Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.birthday as birthday0_ from spring_student student0_
Student: yangfei
Student: zhangsan
Student: lisi
Student: zhaoliu
====begin transaction====
Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, student0_.birthday as birthday0_0_ from spring_student student0_ where student0_.id=?
Hibernate: delete from spring_student where id=?
====commit transaction====
====begin transaction====
Hibernate: select max(id) from spring_student
Hibernate: insert into spring_student (name, birthday, id) values (?, ?, ?)
====commit transaction====
====begin transaction====
Hibernate: update spring_student set name=?, birthday=? where id=?
====commit transaction====
不过这里有个问题,ProxyFactoryBean一次只能给一个Bean织入切面,如果我们Bean要足够多的话,显然会把配置文件搞的非常庞大。幸运的是spring还提供了另一个类org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator,可以一次给多个Bean配置多个Advisor。当然,在使用Bean时,就不能直接用它BeanNameAutoProxyCreator的id了,而只能使用Bean各自的id,取出来的就是代理对象了。
<beans>
  <bean id="targetDao" class="com.yangfei.spring.advisor.dao.StudentDaoImpl"></bean>
  <bean id="targetDao2" class="com.yangfei.spring.advisor.dao.StudentDaoImpl"></bean>
  <bean id="transAdvice" class="com.yangfei.spring.advisor.advice.TransactionAdvice"></bean>
  <bean id="transAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice">
      <ref local="transAdvice"/>
    </property>
    <property name="mappedNames">
      <list>
        <value>insert</value>
        <value>delete</value>
        <value>modify</value>
      </list>
    </property>
  </bean>
  <bean id="test" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<property name="interceptorNames">
      <list>
        <value>transAdvisor</value>
      </list>
    </property>
    <property name="beanNames">
      <list>
        <value>targetDao</value>
        <value>targetDao2</value>
      </list>
    </property>
  </bean>
</beans>

转载于:https://blog.51cto.com/yangfei520/246283

Advice只有切面化之后才能显现出AOP的巨大优势相关推荐

  1. 灰色系装修风格怎么做才能显高级,温馨?

    装修中好看百搭的色彩有很多,但是经典与时尚并存的颜色并不多,可以做到慵懒.温馨并且看不腻的.估计就只有高级灰了. 高级灰游走于黑白之间,没有黑色的冷硬,也没有白色的明亮刺眼,它是中性的.不偏不倚的.非 ...

  2. webflux切面拦截权限,webflux整合aop,webflux获取request

    背景 在springboot+tomcat应用中获取request对象可以使用RequestContextHolder.getRequestAttributes()的方式来获取,此种方式的核心在于re ...

  3. java 切面 不执行,解决springboot的aop切面不起作用问题(失效的排查)

    检查下springboot的启动类是否开启扫描 @springbootapplication @componentscan(basepackages = {"com.zhangpu.spri ...

  4. spring3: 切面及通知实例 Aspectj的aop

    1.前置通知 接口: package chapter1.server;public interface IHelloService {public void sayAdvisorBefore(Stri ...

  5. 容器化部署与传统部署的区别及优势

    编者按:随着互联网技术的发展和需求上的增加,从传统的物理服务器时代过渡到了容器化部署时代,那么容器化部署我们怎么去理解,以及它有什么优势呢?跟小编一起看看吧. 容器化部署与传统部署的区别 以Docke ...

  6. 森林防火监控高集成化设备相比普通设备有哪些显著优势?

    在森林防火监控领域中,这两年兴起了众多新概念和新技术,其中也不乏许多空泛的概念,如"云技术""识别引擎""智慧""前端感知&quo ...

  7. Spring 面向切面编程 第3关:AOP实现原理-JDK动态代理

    目录 任务描述 相关知识 代理模式(Proxy) AOP实现的两种方式 JDK动态代理步骤 案例模拟AOP实现 代理类说明 编程要求 测试说明 参考代码 任务描述 我们知道,Spring AOP的主要 ...

  8. Spring 面向切面编程 第4关:AOP实现原理-CgLib动态代理

    目录 任务描述 相关知识 代理模式(Proxy) AOP实现的两种方式 CGLIB动态代理步骤 模拟AOP实现 代理类说明 编程要求 测试说明 参考代码 任务描述 我们知道,Spring AOP的主要 ...

  9. 米米商城项目实战(含项目源码)

    目录 前言 1. 功能简介+项目展示 2. 数据库表 3. SSM框架 3.1 新建项目 3.2 目录改造 3.3 pom.xml文件 3.4 jdbc.properties 3.5 SqlMapCo ...

最新文章

  1. 迁移到MySQL的业务架构演进实战
  2. 检查mysql当前状态
  3. cordova使用cordova-plugin-baidumaplocation插件获取定位
  4. 在云服务器上持续运行springboot项目
  5. 解决Tomcat下源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示
  6. 在Corporate Network里配置SAP Cloud Connector连接SAP云平台,需要设置代理
  7. 在AWS Elastic MapReduce上运行PageRank Hadoop作业
  8. pcl里面的RoPs特征(Rotational Projection Statistics)
  9. oracle查询表字段横向排序,sql 查询 - 横着走的螃蟹 - OSCHINA - 中文开源技术交流社区...
  10. 《C#初学者指南》一第1章 初识C#
  11. java 后台 小程序微信支付
  12. 第十三次CCF CSP认证(2018年3月)真题URL映射
  13. CSS设置一行文字,超出部分自动隐藏
  14. pyecharts制作中国疫情地图
  15. 关于培训机构~程序员培训
  16. 实验室设备管理系统mysql
  17. uclinux 嵌入式linux,2017最新嵌入式操作系统uCLinux分析
  18. vim-python怎么用_技术|如何在使用 Vim 时访问/查看 Python 帮助
  19. 50Projects--Blurry Loading
  20. 第二课、《抓包学习——美团评论》

热门文章

  1. Microsoft Deployment Toolkit 2010 新功能实战之三
  2. 港媒:中国将斥资1800亿美元建全球最大5G网络
  3. Hadoop核心之HDFS 架构设计
  4. RHCE系列之权限管理----ACL(访问控制列表)
  5. 敏捷开发基础篇(一)-流程与角色基本概念
  6. 转:使用NSOperationQueue简化多线程开发
  7. 容灾技术中的数据一致性保障
  8. TCP/IP与OSI的特征对比总结
  9. Python3 格式化数字 补零 数字补零
  10. pytorch: MaxUnpool2d 与 Upsampling