700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 静态代理 JDK与Cglib动态代理简单实现

静态代理 JDK与Cglib动态代理简单实现

时间:2019-12-06 21:51:30

相关推荐

静态代理 JDK与Cglib动态代理简单实现

目录

1、静态代理2、JDK动态代理3、CgLib动态代理4、三种代理方式区别5、AOP使用了那种代理模式

代理对象就是:即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

1、静态代理

静态代理在使用时:需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。

实现步骤:

1、被代理对象实现接口或者基础父类。

2、代理对象与被代理对象一起实现相同的接口或者是继承相同父类。

3、代理对象的构造方法需要传入被代理对象的接口或者符父类。

4、在代理对象中调用被代理对象的方法,并且在调用前后可以加入自定义条件,作为前置增强和后置增强。

2、代理对象与被代理对象一起实现相同的接口或者是继承相同父类。

// 父类/接口public interface Country {void sayHello();}// 被代理对象public class China implements Country {@Overridepublic void sayHello() {System.out.println("这里是中国");}}// 代理对象public class ChinaProxy implements Country {private Country country;public ChinaProxy(Country country) {this.country = country;}@Overridepublic void sayHello() {System.out.println("调用前");country.sayHello();System.out.println("调用后");}}// 调用者public class Main {public static void main(String[] args) {// 想要访问的对象,一个叫做China的国家Country country = new China();// 获取代理对象实例ChinaProxy proxy = new ChinaProxy(country);// 访问代理对象的具体方法proxy.sayHello();}}

运行结果:

2、JDK动态代理

JDK动态代理只能对实现了接口的类进行代理,主要通过InvocationHandler接口、Proxy类实现。

步骤:

1、 被代理对象实现某个接口。

2、 代理对象实现InvocationHandler接口,代理对象的构造方法需要传入被代理对象的接口。

3、 在重写的invoke方法中,通过method.invoke()调用被代理对象的方法。

4、 在method.invoke()前后可以加入自定义条件,作为前置增强和后置增强。

5、调用者通过代理对象的Proxy.newProxyInstance()方法获取到被代理对象的实例。

// 接口public interface Country {void sayHello();void sayName();}// 被代理对象public class China implements Country {@Overridepublic void sayHello() {System.out.println("你好");}@Overridepublic void sayName() {System.out.println("我是中国");}}// 代理对象public class ChinaProxy implements InvocationHandler {private Country country;public ChinaProxy(Country country) {this.country = country;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("调用代理对象方法前的增强处理");Object invoke = method.invoke(country, args);System.out.println("调用代理对象方法后的增强处理");return invoke;}public Object getInstance() {return Proxy.newProxyInstance(country.getClass().getClassLoader(),country.getClass().getInterfaces(), this);}}// 调用者public class Main {public static void main(String[] args) {// 想要访问的对象,一个叫做China的国家Country country = new China();// 要访问China必须要他的代理同意ChinaProxy proxy = new ChinaProxy(country);// 获取被代理对象实例Country china = (Country) proxy.getInstance();// 访问代理对象的具体方法china.sayHello();System.out.println("-------------");china.sayName();}}

运行结果:

3、CgLib动态代理

Cglib动态代理:目标对象只是一个单独的对象没有实现接口或者基础父类,使用以目标对象子类的方式类实现代理,这种方法就叫做Cglib代理。

注意:

Spring AOP就是使用了cglib代理,使用时需要引入cglib.jar包,代理对象不能为final,目标对象的方法不能为final/static

步骤:

1、引入cglib jar包。

2、定义被代理对象。

3、代理对象实现MethodInterceptor接口,代理对象的构造方法,需要传入一个Object类型的被代理对象。

4、重写intercept方法,通过method.invoke()方法调用被代理对象的方法。

5、在method.invoke()前后可以加入自定义条件,作为前置增强或和后置增强。

6、调用者通过代理对象的Enhancer类创建子类代理对象实例。

//被代理对象public class China {public void sayHello() {System.out.println("你好");}public void sayName() {System.out.println("我是中国");}}// 代理对象public class ChinaProxy implements MethodInterceptor {private Object target;public ChinaProxy(Object target) {this.target = target;}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("调用前增强");Object invoke = method.invoke(target, objects);System.out.println("调用后增强");return invoke;}public Object getInstance() {//工具类Enhancer en = new Enhancer();//设置父类en.setSuperclass(target.getClass());//设置回调函数en.setCallback(this);//创建子类代理对象return en.create();}}// 调用者public class Main {public static void main(String[] args) {// 想要访问的对象,一个叫做China的国家China china = new China();// 要访问China必须要他的代理同意ChinaProxy proxy = new ChinaProxy(china);// 获取子类代理对象实例China chinaProxy = (China) proxy.getInstance();// 访问代理对象的具体方法chinaProxy.sayHello();System.out.println("-------------");chinaProxy.sayName();}}

运行结果:

4、三种代理方式区别

静态代理:在程序运行前,代理类的.class文件就已经存在了,事先知道目标对象是什么,一个代理对象就有实现一个接口。

动态代理类:在程序运行时,运用反射机制动态创建而成,只有在运行时才知道目标对象是什么。

静态代理:被代理对象需要实现接口或基础父类。

JDK动态代理:被代理对象需要实现接口。

CgLib代理:被代理对象为一个单独的对象。

动态代理好处:免于写重复的接口,更加关注方法的增强,降低了代码冗余。

5、AOP使用了那种代理模式

在Spring的AOP编程中:

如果加入容器的目标对象有实现接口,用JDK代理。

如果目标对象没有实现接口,用Cglib代理。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。