三、AOP编程

关注点代码:除了业务代码以外的代码.比如开启事务,关闭事务,异常处理
核心业务代码:保存用户这一句才是重点.
例子如下:
// 保存一个用户
public void add(User user) {
Session session = null;
Transaction trans = null;
try {
session = HibernateSessionFactoryUtils.getSession(); // 【关注点代码】
trans = session.beginTransaction(); // 【关注点代码】

session.save(user); // 核心业务代码

trans.commit(); //…【关注点代码】

} catch (Exception e) {
e.printStackTrace();
if(trans != null){
trans.rollback(); //..【关注点代码】

}
} finally{
HibernateSessionFactoryUtils.closeSession(session); ////..【关注点代码】

}
}

为了提高代码效率,会让核心代码和业务代码分离.实现的方法就是代理模式.

名词解释:
AOP面向切面编程:
让关注点代码与业务代码分离(面向切面编程就是面向重复代码编程)
关注点:
很多重复代码形成的类和方法

切面:
关注点形成的类。(公共的类)
面向切面编程与面向接口编程:
面向切面编程比面向接口编程更加抽象,面向切面编程公有属性和行为,抽象为面向切面。
面向接口编程,各个对象的公共方法抽取出来,放到父类和接口当中,接口当中定义类的公用行为。
面向切面编程很多重复的功能,抽象出来,比如工厂类
应用:
面向切面编程用在后期优化的时候使用。
切入点(指定拦截的是哪个点,拦截哪些方法):
执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法。给指定的类在运行的时候植入切面类代码

Aop代理实现了两种,一种是jdk代理,一种是cglib代理.
Aop实现的其实是通过,切面类的拦截,从而进行动态代理,使得多个重复的代码和方法,抽象出来,增强代码的强壮性和代码的优化性能.

1、注解方式实现AOP编程

步骤:
1) 先引入aop相关jar文件 (aspectj aop优秀组件)
spring-aop-3.2.5.RELEASE.jar 【spring3.2源码】
aopalliance.jar 【spring2.5源码/lib/aopalliance】
aspectjweaver.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
aspectjrt.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】

注意: 用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题。
需要升级aspectj组件,即使用aspectj-1.8.2版本中提供jar文件提供。

2) bean.xml中引入aop名称空间

<context:component-scan base-package="com.liuyang.annotation.proxy"></context:component-scan>

3) 开启aop注解

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

4) 使用注解
@Aspect 指定一个类为切面类
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))") 指定切入点表达式

@Before("pointCut_()") 前置通知: 目标方法之前执行
@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()") 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知: 出现异常时候执行
@Around("pointCut_()") 环绕通知: 环绕目标方法执行

事例:

(1)建立UserDao

    public interface UserDao {

     public void save();

 }

(2)建立MyUserDaoAop

    @Component
public class MyUserDaoAop implements UserDao { @Override
public void save() {
System.out.println("******核心业务的实现*****");
} }

(3)建立AOP

    @Component
// 指定当前类为切面类
@Aspect
public class Aop { // 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象
@Pointcut("execution(* com.liuyang.annotation.proxy.*.*(..))")
public void pointCut_() {
} // 前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin() {
System.out.println("开始事务/异常");
} // 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after() {
System.out.println("提交事务/关闭");
} // 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning() {
System.out.println("afterReturning()");
} // 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing() {
System.out.println("afterThrowing()");
} // 环绕通知:环绕目标方式执行
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前....");
pjp.proceed(); // 执行目标方法
System.out.println("环绕后....");
} }

(4)建立bean.xml

    <?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 开启注解扫描 -->
<context:component-scan base-package="com.liuyang.annotation.proxy"></context:component-scan> <!-- 开启AOP注解模式 ,默认false采用jdk代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

(5)建立非接口模式的代理

    @Component
// 加入容器
@Scope("prototype")
public class OrderDao { public void save() {
System.out.println("-----核心业务:保存2222!!!------");
}
}

(6)建立测试

     public class TestAop {

     // 目标对象有实现接口,spring会自动选择“JDK代理”
@Test
public void testApp() {
ApplicationContext aContext = new ClassPathXmlApplicationContext(
"com/liuyang/annotation/proxy/bean.xml");
UserDao userDao = (UserDao) aContext.getBean("myUserDaoAop");
System.out.println(userDao.getClass());// $Proxy001
userDao.save();
} // 目标对象没有实现接口, spring会用“cglib代理”
@Test
public void testCglib() {
ApplicationContext aContext = new ClassPathXmlApplicationContext(
"com/liuyang/annotation/proxy/bean.xml");
OrderDao orderDao = (OrderDao) aContext.getBean("orderDao");
System.out.println(orderDao.getClass());
orderDao.save();
} @Deprecated
// 共性问题:如果目标对象有实现接口,在从容器中获取目标对象的时候,只能通过接口接收对象。
public void testApp2() {
ApplicationContext aContext = new ClassPathXmlApplicationContext(
"com/liuyang/annotation/proxy/bean.xml");
// 错误代码: 只能用接口接收
UserDao userDao = (UserDao) aContext.getBean("myUserDaoAop");
System.out.println(userDao.getClass());// $Proxy001
userDao.save();
} @Test
public void testGetObj() throws Exception {
ApplicationContext aContext = new ClassPathXmlApplicationContext(
"com/liuyang/annotation/proxy/bean.xml");
OrderDao orderDao1 = (OrderDao) aContext.getBean("orderDao");
OrderDao orderDao2 = (OrderDao) aContext.getBean("orderDao"); System.out.println(orderDao1);
System.out.println(orderDao2); } }

Spring框架总结(九)的更多相关文章

  1. Spring框架系列(九)--MyBatis面试题(转载)

    1.什么是Mybatis? 1.Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建 连接.创建statement ...

  2. 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)

    文件夹      [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器開始(八)      [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入 ...

  3. Spring框架入门之Spring简介

    一.Spring简介(由Rod Johnson创建的一个开源框架)        Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿 ...

  4. spring boot / cloud (九) 使用rabbitmq消息中间件

    spring boot / cloud (九) 使用rabbitmq消息中间件 前言 rabbitmq介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.它可以用于大型软件系统 ...

  5. spring Boot(十九):使用Spring Boot Actuator监控应用

    spring Boot(十九):使用Spring Boot Actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台 ...

  6. Spring框架总结(十)

    XML方式实现AOP编程 Xml实现aop编程: 1) 引入jar文件 [aop 相关jar, 4个] 2) 引入aop名称空间 3)aop 配置 * 配置切面类 (重复执行代码形成的类) * aop ...

  7. 基于java spring框架开发部标1078视频监控平台精华文章索引

    部标1078视频监控平台,是一个庞杂的工程,涵盖了多层协议,部标jt808,jt809,jt1078,苏标Adas协议等,多个平台功能标准,部标796标准,部标1077标准和苏标主动安全标准,视频方面 ...

  8. Spring系列(2):Spring框架

    一.Spring定义 Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用. Spring是于2003 年兴起的一个轻量级 ...

  9. Spring框架之beans源码完全解析

    导读:Spring可以说是Java企业开发里最重要的技术.而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmin ...

  10. Spring框架之spring-web web源码完全解析

    Spring框架之spring-web web源码完全解析 spring-web是Spring webMVC的基础,由http.remoting.web三部分组成,核心为web模块.http模块封装了 ...

随机推荐

  1. 029:高可用之MHA

    高可用之MHA 一.MHA 简介 MHA(Master High Availability)是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件.在MySQL故障切换过程中,MHA能 ...

  2. JAVA中的IO流介绍(2)

    一.流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等. 一个流,必有源端和目的端, ...

  3. maven release plugin插件

    1.打包版本区别 SNAPSHOT 快照版本(开发阶段,不稳定,容易出现bug)RELEASE 正式版本(外部依赖使用阶段,稳定,很少出现bug)Tag :标记每次代码提交的版本(比较稳定,类似分支) ...

  4. REST理解

    内容摘自:<Spring REST> REST是什么:REST是一种软件架构风格,它由建立规模可扩展的web服务的最佳实践和指南构成. 资源: 一切可被访问和操作的东西.资源标识:URI( ...

  5. Java Ant Build详解

    转载地址:http://www.cnblogs.com/wufengxyz/archive/2011/11/24/2261797.html 1,什么是antant是构建工具2,什么是构建概念到处可查到 ...

  6. CBV 验证装饰器的使用

    下面是3种方式: from django.shortcuts import render, redirect from django.views import View # Create your v ...

  7. Spring boot + Gradle + Eclipse打war包发布总结

    首先感谢两位博主的分享 http://lib.csdn.net/article/git/55444?knId=767 https://my.oschina.net/alexnine/blog/5406 ...

  8. oracle常用函数总结(二)

    之前也有写过“oracle常用函数总结(一)”,为了尽量找全常见oracle函数,笔者特意查找了相关资料来作为参考,下边给大家罗列出来,部分和之前有重复的,希望能帮到大家! 列举了31个函数和1个分组 ...

  9. javascript常见方法汇总之一——数组字符串相关

    (转载至慕课网) 原文链接:https://www.imooc.com/article/46933 github地址:https://github.com/dorseysen/notes-about- ...

  10. idea使用jrebel热部署插件

    首先通过idea下载JReble插件 访问http://idea.lanyus.com/网站 跟着弹出框的步骤走就可以实现了: 在idea中使用tomcat部署项目 不要使用war:使用下面的文件