三、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. 基于Keepalived高可用集群的MariaDB读写分离机制实现

    一 MariaDB读写分离机制 在实现读写分离机制之前先理解一下三种主从复制方式:1.异步复制:MariaDB默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库 ...

  2. Java web概述

    声明:为了使初学者能更好的了解java web,所以我整理了下资料,概述了web应用程序. 一.web概述 静态web资源:内容是静态的,不同的人在不同的时间来访问时都是相同的内容.HTML.CSS. ...

  3. Python handling an exception

    #try...except... try: You do your operations here; ...................... except ExceptionI: If ther ...

  4. js控制手机震动

    js控制手机震动 <button onclick="vibrate()">震动</button> <script> function vibra ...

  5. 12.solr学习速成之dataimport

    solr除了利用solrj建立索引外,还可以由列式数据库hbase触发器添加索引,自动全量或者增量索引关系数据库数据等. dataimport可以配置从任何关系数据库导入索引 1.将jar包拷贝到to ...

  6. 编码转换(UTF8->GBK)

    WCHAR woutstr[]; ]; , value, -, NULL, ); MultiByteToWideChar(CP_UTF8, , value, -, woutstr, len); len ...

  7. openssh 在32位、64位操作系统上的安装配置

    openssh是安装在windows系统上的提供SSH服务的服务端软件,可以提供安全的命令行远程连接管理.下面介绍下openssh成功安装使用的操作步骤. 工具/原料   openssh window ...

  8. Linux常用命令大全(全面)

    笔者在这篇文章中跟大家分享一下接近 100 个 Linux 常用命令大全,希望可以帮助到大家. 1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 1 2 3 4 5 6 7 8 9 1 ...

  9. 关于git的reset、checkout、revert

    https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/file-level-operations 最 ...

  10. SWFUpload初体验 For Struts1.x

    SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统<input ty ...