1.代理模式readMe:

代理设计模式: 是java中常用的设计模式!

   特点:
.委托类和代理类有相同的接口或者共同的父类!
.代理类为委托类负责处理消息,并将消息转发给委托类!
.委托类和代理类对象通常存在关联关系!
一个代理类对象与一个委托类对象关联!
.代理类本身并不是真正的实现者!而是通过调用委托类的方法,
来实现功能! 按照代理类创建的时机,代理类分为两种:
.静态代理:由我们程序猿或者特定的工具自动生成了源代码,
在程序运行之前,.class文件已经存在了!
(serviceImpl 调用了 dao层的方法! 真正的实现是Dao)
.动态代理:在程序运行期间,通过反射的方式动态的创建出来! 按照我们的使用方式: 是由共同的接口还是公共的父类? .jdk动态代理 (接口)
必须知道一个类和一个接口
.InvocationHandler接口只有一个方法 public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable; proxy:代理类对象
method:被代理的方法
args:被代理的方法的参数列表 .Proxy 类:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException
loader:类加载器
interfaces:代理类实现的所有接口
h:InvocationHandler接口的一个实例 this当前对象
因为我们想使用jdk动态代理 必须是 代理类 实现 InvocationHandler!
它让我们传递父接口 我们传递 自身! .cglib动态代理(接口+父类)
必须知道一个类和一个接口
.MethodInterceptor接口 public Object intercept(Object obj,
Method method,Object[] args,MethodProxy proxy) throws Throwable; intercept是所有拦截器执行的方法,类似于jdk动态代理中的invoke . Enhancer类 设置委托类和代理类的公共接口或者公共的父类
public void setSuperclass(Class superclass) {
if (superclass != null && superclass.isInterface()) {
setInterfaces(new Class[]{ superclass });
} else if (superclass != null && superclass.equals(Object.class)) {
// affects choice of ClassLoader
this.superclass = null;
} else {
this.superclass = superclass;
}
} 代理类执行完毕 通知委托类
public void setCallback(final Callback callback) {
setCallbacks(new Callback[]{ callback });
} 在Enhancer类的父类AbstractClassGenerator中有一个方法
创建我们需要的代理类
protected Object create(Object key)

2.静态代理:

01.接口代码:

package cn.pb.dao;

/**
* 动物类 父接口
*/
public interface Animal {
//主业务
void eat();
void sleep();
}

02.实现类代码:

package cn.pb.dao.impl;
/**
* 狗狗类 实现了Animal接口
*/ import cn.pb.dao.Animal; public class Dog implements Animal {
public void eat() {
System.out.println("狗狗在啃骨头!");
} public void sleep() {
System.out.println("狗狗在午休!");
}
}

03.静态代理类:

package cn.pb.staticproxy;

import cn.pb.dao.Animal;
import cn.pb.dao.impl.Dog; /**
* 狗狗的静态代理类
*/
public class AnimalStaticProxy implements Animal { private Dog dog; public void sleep() {
System.out.println("主人在召唤"); //系统级业务
dog.sleep();
System.out.println("主人离开"); //系统级业务
} public void eat() {
System.out.println("主人在召唤"); //系统级业务
dog.eat();
System.out.println("主人离开"); //系统级业务
} public Dog getDog() {
return dog;
} public void setDog(Dog dog) {
this.dog = dog;
} /**
* 我们发现的问题
* 01:代码冗余
* 02:把冗余的代码提取成公共的方法
* 03:有可能小猫咪也有这些方法
* 04:提取成一个工具类中的方法
* 05:现在有一个小猫咪 也需要执行 sleep和eat 以及系统级业务方法
* 06:我们又得创建一个小猫咪对应的代理类
* 07:动物有很多 ,难道需要我们创建N个代理类吗??肯定!
*/
}

04.测试类代码:

 /**
* 静态代理的测试方法
*/
@Test
public void testStaticProxy(){
AnimalStaticProxy proxy = new AnimalStaticProxy();
Dog dog=new Dog();
proxy.setDog(dog); proxy.eat();
System.out.println("*************");
proxy.sleep();
}

3.JDK动态代理:

01.接口代码:

package cn.pb.dao;

/**
* 动物类 父接口
*/
public interface Animal {
//主业务
void eat();
void sleep();
}

02.实现类代码:

package cn.pb.dao.impl;
/**
* 狗狗类 实现了Animal接口
*/ import cn.pb.dao.Animal; public class Dog implements Animal {
public void eat() {
System.out.println("狗狗在啃骨头!");
} public void sleep() {
System.out.println("狗狗在午休!");
}
}

03.动态代理类代码:

package cn.pb.jdkdynamicproxy;
/**
* JDK的动态代理类
*/ import cn.pb.dao.Animal;
import cn.pb.dao.impl.Dog; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class AnimalJdkDynamicProxy implements InvocationHandler { /**
* 01.我们不确定委托类是谁?委托类的类型 是Object
* 和委托类建立关联关系
*/
private Object target; /**
* 02.给我一个委托类,我返回一个代理类对象
*/
public Object createProxy(Object target){
//根据传递的参数 进行对象的关联
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
} /**
*
* @param proxy :代理对象
* @param method :方法名
* @param args : 参数列表
* @return
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("主人在召唤"); //系统级业务 开始事务
Object result= method.invoke(target,args); // 主业务
System.out.println("主人离开"); //系统级业务 日志处理 关闭事务
return result;
} //创建测试方法
public static void main(String[] args) {
AnimalJdkDynamicProxy proxy=new AnimalJdkDynamicProxy();
Animal dog= (Animal) proxy.createProxy(new Dog());
dog.eat();
System.out.println("**************************");
dog.sleep(); }
}

04.测试代码:

 @Test
public void testJdkDynamicProxy(){
AnimalJdkDynamicProxy proxy=new AnimalJdkDynamicProxy();
Animal dog= (Animal) proxy.createProxy(new Dog());
dog.eat();
System.out.println("**************************");
dog.sleep();
}

4.cglib动态代理:

01.接口代码:

package cn.pb.dao;

/**
* 动物类 父接口
*/
public interface Animal {
//主业务
void eat();
void sleep();
}

02.实现类代码:

package cn.pb.dao.impl;
/**
* 狗狗类 实现了Animal接口
*/ import cn.pb.dao.Animal; public class Dog implements Animal {
public void eat() {
System.out.println("狗狗在啃骨头!");
} public void sleep() {
System.out.println("狗狗在午休!");
}
}

03.动态代理类代码:

package cn.pb.cglibdynamicproxy;

/**
* Cglib动态代理
*/
import cn.pb.dao.Animal;
import cn.pb.dao.impl.Dog;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class AnimalCglibDynamicProxy implements MethodInterceptor { /**
* 在enhancer中有一个setCallBack(this)
* 这样就实现了代理类和委托类的关联
*/
private Enhancer enhancer=new Enhancer(); /**
* 创建代理类对象
*/
public Object createProxy(Class clazz){
//设置公共的接口或者公共的类
enhancer.setSuperclass(clazz);
//建立关联关系
enhancer.setCallback(this);
return enhancer.create();
} /**
* 类似于我们jdk中的invoke
*/
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("主人在召唤"); //系统级业务 开始事务
Object result= proxy.invokeSuper(obj,args); // 主业务
System.out.println("主人离开"); //系统级业务 日志处理 关闭事务
return result;
} //创建测试方法
public static void main(String[] args) {
AnimalCglibDynamicProxy proxy=new AnimalCglibDynamicProxy();
//这里的参数可以传三种形式01:new Dog().getClass()
// 02:Class.forName("cn.pb.dao.impl.Dog") 03.Dog.class
Animal dog= (Animal) proxy.createProxy(new Dog().getClass());
dog.eat();
System.out.println("**************************");
dog.sleep();
}
}

04.测试代码:

  @Test
public void testCglibDynamicProxy(){
AnimalJdkDynamicProxy proxy=new AnimalJdkDynamicProxy();
Animal dog= (Animal) proxy.createProxy(new Dog());
dog.eat();
System.out.println("**************************");
dog.sleep();
}

Spring笔记06(Spring AOP的底层实现动态代理)的更多相关文章

  1. 浅析Spring中AOP的实现原理——动态代理

    一.前言   最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...

  2. 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】

    一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...

  3. Spring AOP学习笔记04:AOP核心实现之创建代理

    上文中,我们分析了对所有增强器的获取以及获取匹配的增强器,在本文中我们就来分析一下Spring AOP中另一部分核心逻辑--代理的创建.这部分逻辑的入口是在wrapIfNecessary()方法中紧接 ...

  4. spring学习06(AOP)

    9.AOP 什么是AOP AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软 ...

  5. Spring笔记(三)AOP前篇之动态代理

    AOP思想是将程序中的业务代码与服务代码进行分离,在运行时进行结合.比较强调程序的层次结构,是一种面向切面的编程.而在AOP实现的底层主要用到了动态代理,而动态代理又分为JDK动态代理和CGLIB动态 ...

  6. Spring笔记(7) - Spring的事件和监听机制

    一.背景 事件机制作为一种编程机制,在很多开发语言中都提供了支持,同时许多开源框架的设计中都使用了事件机制,比如SpringFramework. 在 Java 语言中,Java 的事件机制参与者有3种 ...

  7. Spring笔记(4) - Spring的编程式事务和声明式事务详解

    一.背景 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作 ...

  8. 二)Spring AOP编程思想与动态代理

    一.aop编程思想 1.面向切面,就是能够不动源码的情况下,从横切面切入新的代码功能. 2.实现原理是动态代理 动态代理的步骤 a.写生产厂家,实现接口,代理只能代理接口 b.动态代理类实现Invoc ...

  9. 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理

    之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...

随机推荐

  1. STL源代码剖析 容器 stl_vector.h

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie vector --------------------------------------- ...

  2. Atom 编辑器使用和学习

    事先准备:下载 Github 开源文本编辑器 Atom,并安装Atom 官网 | 搜索 “Atom下载” 常用快捷键:http://blog.csdn.net/hunyxv/article/detai ...

  3. 贷前系统ElasticSearch实践总结

    贷前系统负责从进件到放款前所有业务流程的实现,其中涉及一些数据量较大.条件多样且复杂的综合查询,引入ElasticSearch主要是为了提高查询效率,并希望基于ElasticSearch快速实现一个简 ...

  4. Java学习之路 第四篇 oop和class (面向对象和类)

    本人水平有限,创作本文是为了记录学习和帮助初学者学习,欢迎指正和补充 一.面向对象编程的设计概述 很多同学都在学校学了电脑的编程,现在的书籍大部分都是oop面向对象编程,一个很抽象的的名字,比较难以理 ...

  5. OpenCV 入门示例之五:一个复杂点的变换

    前言 前文介绍了一个简单的变换.需要注意的是,很多时候,输出和输入图像的格式是不同的( 大小,深度,通道 ).在本文将展示的程序中,对图像进行了缩放( 使用cvPyrDown 函数 ),这种情况下需要 ...

  6. 深入理解JVM:JVM执行时数据区域分类

    JVM在运行java程序的过程中会把他所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途和创建.销毁时间.有些区域随着虚拟机的启动而存在.有些区域则依赖用户线程的启动和结束而建立和销毁. ...

  7. hdu2473 Junk-Mail Filter 并查集+删除节点+路径压缩

    Description Recognizing junk mails is a tough task. The method used here consists of two steps:  1) ...

  8. 提高Interface Builder高效工作的8个技巧

    本文转载至 http://www.cocoachina.com/ios/20141106/10151.html iOS开发Interface Builder 本文译自:8 Tips for worki ...

  9. python 基础 9.1 连接数据库

    二.数据库连接 MySQLdb 提供了connect 方法用来和数据库建立连接,接收数个参数,返回连接对象: #/usr/bin/python #coding=utf-8 #@Time   :2017 ...

  10. EasyNVR H5流媒体服务器方案架构设计之视频能力平台

    历经过程 阶段一:经历过传统安防开发过程的开发者都有一种感觉,就是各种业务交织,各个模块的开发扯皮,各种数据库连接冲突,这很让开发工作效率很低,而且会给整体的开发带来负面影响,更重要的是,耦合度太高, ...