静态代理比较简单,就是代理对象与被代理对象继承相同的接口,代理类负责调用被代理类(委托类)的对象的相关方法去提供具体的服务,一个代理类只能为一个接口服务,要是有很多服务的话需要开很多代理类。而动态代理则是由反射实现,可以用一个代理类实现所有的代理功能,这点是比较方便的。

先看看静态代理:

一个接口类,若干个接口实现类和一个代理类即可

接口

package proxy;

public interface Women {
public void eat();
public void play(); }

接口实现类一

package proxy;

public class Lily implements Women{

    @Override
public void eat() {
System.out.println("i'm Lily,i love eat banana");
} @Override
public void play() {
System.out.println("i'm Lily,i love swimming");
} }

接口实现类二

package proxy;

public class Juli implements Women{

    @Override
public void eat() {
System.out.println("i'm Juli,i love eat banana");
} @Override
public void play() {
System.out.println("i'm Juli,i love swimming");
} }

代理类

package proxy;

public class Proxy implements Women{
private Women women;
public Proxy(){
this.women=new Lily();//设一个代理的默认值
}
public Proxy(Women women){
this.women=women;
}
@Override
public void eat() {
this.women.eat();
}
@Override
public void play() {
this.women.play();
} }

测试

package proxy;

public class StaticProxyTest {
public static void main(String[] args) {
Proxy p;
p=new Proxy();
p.eat();
p.play();
p=new Proxy(new Juli());
p.eat();
p.play();
} }

测试结果 

i'm Lily,i love eat banana
i'm Lily,i love swimming
i'm Juli,i love eat banana
i'm Juli,i love swimming

动态代理的话主要有两种实现方式,一种是jdk动态代理实现,一种是cglib代理。JDK动态代理只能针对实现了接口的类生成代理,CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,

主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。

先看看jdk代理

代理类

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler{
private Women women;
public JdkProxy(Women women){
this.women=women;
}
public static Women newProxyInstance(Women women){
return (Women) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), new Class<?>[] { Women.class }, new JdkProxy(women)); } @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(women, args);
} }

改成通用点的

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler{ private Object obj;
public JdkProxy(Object obj){
this.obj=obj;
}
public static Object newProxyInstance(Object targetObject){//传入的是类的实现接口
return Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), targetObject.getClass().getInterfaces(),new JdkProxy(targetObject)); } @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(this.obj, args);
} }

  

测试类 

package proxy;

public class JdkProxyTest {
public static void main(String[] args) {
Women women= JdkProxy.newProxyInstance(new Lily());
women.eat();
women.play();
} } 

 

测试结果

i'm Lily,i love eat banana
i'm Lily,i love swimming

  

Cglib代理类

package proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor {
private CglibProxy() {
}
public static <T extends Women> Women newProxyInstance(Class<T> targetInstanceClazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetInstanceClazz);
enhancer.setCallback(new CglibProxy());
return (Women) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例 } @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
} }

改成通用点的

package proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor {
private CglibProxy() {
}
public static <T extends Object> Object newProxyInstance(Class<T> targetInstanceClazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetInstanceClazz);
enhancer.setCallback(new CglibProxy());
return (Object) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例 } @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
} }

 

测试 

package proxy;

public class CglibTest {
public static void main(String[] args) {
Women women = (Women) CglibProxy.newProxyInstance(Lily.class);
women.eat();
women.play();
} }

测试结果 

i'm Lily,i love eat banana
i'm Lily,i love swimming

  

 

java代理与动态代理的学习的更多相关文章

  1. JAVA学习篇--静态代理VS动态代理

    本篇博客的由来,之前我们学习大话设计,就了解了代理模式,但为什么还要说呢? 原因: 1,通过DRP这个项目,了解到了动态代理,认识到我们之前一直使用的都是静态代理,那么动态代理又有什么好处呢?它们二者 ...

  2. Java设计模式学习06——静态代理与动态代理(转)

    原地址:http://blog.csdn.net/xu__cg/article/details/52970885 一.代理模式 为某个对象提供一个代理,从而控制这个代理的访问.代理类和委托类具有共同的 ...

  3. java静态代理及动态代理(学习示例)

    1.接口 public interface Channel { void send(); } 2.实现类(可以为各种不同实现) public class ChannelImpl implements ...

  4. java 笔记(3) —— 动态代理,静态代理,cglib代理

    0.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口. 代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存 ...

  5. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  6. java中静态代理跟动态代理之间的区别

    文章转载于:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另 ...

  7. java之静态代理和动态代理

    我们以几个问题,来开始我们今天的学习,如果下面几个问题,你都能说出个一二,那么恭喜你,你已经掌握了这方面的知识.1,什么是代理模式?2,Java中,静态代理与动态代理的区别?3,Spring使用的是J ...

  8. Java中的代理模式--静态代理和动态代理本质理解

    代理模式定义:为其他对象提供了一种代理以控制对这个对象的访问. 代理模式的三种角色: Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求. Real ...

  9. 细说java系统之动态代理

    代理模式 在深入学习动态代理之前,需要先掌握代理模式.只有深刻理解了代理模式的应用,才能充分理解Java动态代理带来的便利. 在生活中存在许多使用"代理模式"的场景,比如:村里的张 ...

  10. java中Proxy(代理与动态代理)

    转自: https://blog.csdn.net/pangqiandou/article/details/52964066 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习 ...

随机推荐

  1. Mysql 中 trim 的用法

    需求:去掉contract字段值中的% update gsfrankfurt set contract = trim(both "%" from contract);

  2. Android Unique Device ID

    There are several occasions when the unique identifier of a device is required. For instance you nee ...

  3. unity3d控制主摄像头移动

    这篇很水,因为就只有一行代码==: Camera.main.transform.Translate (Vector3.forward); 这行代码控制主摄像头向前移动,其它的如下: up:向上 dow ...

  4. [转]android – 多屏幕适配相关

    1.基本概念 屏幕大小(screen size) – 屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸).android把屏幕分为以下4种:small,normal,large,extr ...

  5. Objective-C之成魔之路【5-选择结构】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 Objec ...

  6. Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c#

    Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c# 1. 加密算法的参数::算法/模式/填充 1 2. 标准加密api使用流程1 2.1. Md5——16bi ...

  7. [elk]es增删改查最佳实战

    PUT app01 GET app01/_settings GET _all/_settings PUT app01/_settings { "number_of_replicas" ...

  8. 安装yii2高级应用模板

    composer global require "fxp/composer-asset-plugin:1.0.0" composer create-project --prefer ...

  9. ZThread在Windows下打印若干DEBUG信息到console的原因

    代码见这篇随笔 在Windows下的运行结果:ZThread打印了一堆东西(并不是我写的) 文件结构: 最开始我以为是编译选项没弄对,同样的代码放到Linux下编译,还是打印这些信息 注意我在Linu ...

  10. 转载:JMeter压力测试入门教程[图文]

    JMeter压力测试入门教程[图文] Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可 ...