三、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. 使用CSS3 Flexbox布局

    Flexbox(中文版本可以点击这里)的布局是一个用于页面布局的全新CSS3模块功能.它可以把列表放在同一个方向(从左到右或从上到下排列),并且让这些列表能延伸到占用可用的空间.较为复杂的布局可以通过 ...

  2. SpringMVC+Spring+Mybatis -- 集成之旅

    准备 首先介绍一下,我的工具使用的是STS, 需要的童鞋可以到官网下载:http://spring.io/tools/sts/all 使用STS是因为她集成了Maven进行 “包“ 管理以及自带 We ...

  3. iOS开发API常用英语名词

    iOS开发API常用英语名词 0. indicating 决定 1.in order to 以便 2.rectangle bounds 矩形尺寸 3.applied 应用 4.entirety 全部 ...

  4. 在线pubmed

    ESearch(文本搜索) eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi http://eutils.ncbi.nlm.nih.gov/entr ...

  5. js控制电池

    js控制电池 判断设备是否在充电 navigator.getBattery().then(function(battery){ if(battery.charging) { alert("电 ...

  6. Docker命令大全

    1.容器生命周期管理 run  创建一个新的容器并运行一个命令 语法 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] OPTIONS说明: -a stdin ...

  7. leetcode380

    class RandomizedSet { public: /** Initialize your data structure here. */ RandomizedSet() { } /** In ...

  8. Alternative PHP Cache ( APC )

    简介: Alternative PHP Cache (APC) 是一个开放自由的PHP opcode 缓存.它的目标是提供一个自由.开放和健全的框架用于缓存和优化 PHP 的中间代码,加快 PHP 执 ...

  9. 添加 MyEclipse Persistence Tools 类库

    1).右键点击你的项目,然后选择Properties.2).在 Java Build Path 页面, 在 Libraries 面板下选择 Add Library….3).选择 MyEclipse L ...

  10. spring中bean 的属性id与name