概述
代理模式主要有两种:静态代理和动态代理
静态代理类图之间的关系
静态代理:比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
package com.mypack.proxy;
public interface HelloWorld {
public void sayHelloWorld();
}
B:再定义一个实现类
package com.mypack.proxy;
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println("Hello World....");
}
}
C:定义一个静态代理类
package com.mypack.proxy;
public class StaticProxyFactory implements HelloWorld {
private HelloWorld helloWorld;
public StaticProxyFactory(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
@Override
public void sayHelloWorld() {
System.out.print("Welcome:");
helloWorld.sayHelloWorld();
}
}
D:测试类
package com.mypack.proxy;
import org.junit.Test;
public class Demo {
@Test
public void testHelloWorld() {
HelloWorld helloWorld = new HelloWorldImpl();
StaticProxyFactory staticProxyFactory = new StaticProxyFactory(helloWorld);
staticProxyFactory.sayHelloWorld();
}
}
E:总结:
可以看出静态代理类有一个很不爽的缺点:如果接口加一个方法,所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。
动态代理
动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
动态代理类图之间的关系
JDK提供的代理只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类。
package com.mypack.service;
public interface PersonService {
public void save();
}
package com.mypack.service.impl;
import com.mypack.service.PersonService;
public class PersonServiceBean implements PersonService {
private String user;
public PersonServiceBean() {
}
public PersonServiceBean(String user) {
this.user = user;
}
public void save() {
System.out.println("我是save()方法..........");
}
public String getUser() {
return user;
}
}
package com.mypack.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mypack.service.impl.PersonServiceBean;
public class JDKProxyFactory implements InvocationHandler {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
//Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时执行InvocationHandler的invoke方法
return Proxy.newProxyInstance(this.targetObject.getClass()
.getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean personServiceBean = (PersonServiceBean) this.targetObject;
Object result = null;
if (personServiceBean.getUser() != null) {
result = method.invoke(this.targetObject, args);
}
return result;
}
}
如果想对类进行代理,可以使用Spring中的CGLib,代理类都需要实现MethodInterceptor接口。
package com.mypack.aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.mypack.service.impl.PersonServiceBean;
public class CGLIBProxyFactory implements MethodInterceptor {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
// 新建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置代理目标类
enhancer.setSuperclass(this.targetObject.getClass());
// 方法被拦截时,执行intercept方法。
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxyObject, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean personServiceBean = (PersonServiceBean) this.targetObject;
Object result = null;
if (personServiceBean.getUser() != null) {
result = method.invoke(this.targetObject, args);
}
return result;
}
}
测试类
package com.mypack.test;
import org.junit.BeforeClass;
import org.junit.Test;
import com.mypack.aop.CGLIBProxyFactory;
import com.mypack.aop.JDKProxyFactory;
import com.mypack.service.PersonService;
import com.mypack.service.impl.PersonServiceBean;
public class Demo {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void testJDKProxySave() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService personService = (PersonService) factory
.createProxyInstance(new PersonServiceBean("liudong"));
personService.save();
}
@Test
public void testCGLIBProxySave() {
CGLIBProxyFactory factory = new CGLIBProxyFactory();
PersonService personService = (PersonService) factory
.createProxyInstance(new PersonServiceBean("liudong"));
personService.save();
}
}
- 大小: 7.8 KB
- 大小: 16.3 KB
- 大小: 14.4 KB
分享到:
相关推荐
1. **动态代理**:在Java中,如果我们想要在调用某个方法之前或之后执行一些额外的操作,可以使用Java的内置代理(JDK Proxy)。但是,当目标类没有实现接口时,JDK代理就无法工作了,这时CGLIB就可以派上用场。...
本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...
在Java中,代理模式有多种实现方式,包括静态代理、JDK动态代理和CGLIB动态代理。 **静态代理** 静态代理是最早也是最基础的代理实现方式。在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)...
本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中的选择。 首先,JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类用于创建一个代理对象...
JDK动态代理基于接口,如果目标对象实现了至少一个接口,Spring会使用JDK的Proxy类生成一个代理对象。而如果没有接口或者接口方法不能满足需求,Spring就会退而求其次,使用CGLib来创建代理。在这个过程中,...
JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...
Cglib就是一种实现动态代理的方式,不同于JDK自带的Proxy,Cglib不需要目标对象实现任何接口,因此可以用于不能实现接口的对象。通过Enhancer类,我们可以指定需要代理的目标类,并提供回调方法实现动态代理逻辑。 ...
JDK代理和Cglib代理是两种常用的动态代理实现方式。 **JDK代理(Java Dynamic Proxy)** JDK动态代理是Java标准库提供的一种代理机制,位于`java.lang.reflect`包下的`Proxy`类和`InvocationHandler`接口。JDK代理...
JDK代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。下面将详细解析这些知识点。 首先,`InvocationHandler`接口是JDK代理的核心,它定义了一个方法`invoke(Object proxy,...
动态代理主要分为两种技术:JDK动态代理和CGLIB动态代理。 ### JDK动态代理 JDK动态代理是Java内置的一种机制,依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。以下是JDK动态...
在Java中,JDK提供了一种标准的动态代理机制,但它的局限在于只能代理接口。对于没有实现接口的类,CGLib可以作为一个很好的补充。CGLib通过创建目标类的子类,为这些类提供代理实现,允许我们在不修改源代码的情况...
2. **动态代理**: 对于没有实现接口的类,JDK的java.lang.reflect.Proxy无法直接生成代理对象,此时CGlib就派上了用场。它可以通过创建目标类的子类来提供动态代理功能。 3. **性能优化**: 在某些场景下,如果需要...
主要存在两种常见的动态代理技术:JDK动态代理和CGLIB(Code Generation Library)动态代理。本文将深入探讨这两种技术的区别和原理。 **JDK动态代理**: JDK动态代理是Java标准库提供的一种代理机制,位于`java....
JDK和CGLIB是两种常用的实现Java动态代理的方式。本文将深入探讨这两个库以及它们的工作原理。 **JDK动态代理** JDK动态代理基于Java反射API实现,它提供了`java.lang.reflect.Proxy`类和`java.lang.reflect....
JDK和CGLIB是Java中实现动态代理的两种主要方式,它们在Spring框架中扮演着关键角色,尤其是在AOP(面向切面编程)中。 1. **JDK动态代理**: JDK动态代理基于Java的接口机制实现,因此,要使用JDK动态代理,被...
Java提供了两种主要的代理实现方式:JDK静态代理和动态代理,另外还有第三方库如CGlib提供的代理实现。下面我们将详细探讨这些代理技术,并通过代码演示来理解它们的工作原理。 ### 1. JDK静态代理 静态代理是我们...
1. **无需接口**:JDK动态代理要求被代理的对象必须实现至少一个接口,而CGlib则可以直接代理没有接口的类。 2. **性能较好**:对于未实现接口的类,CGlib的代理速度通常比JDK更快,因为它是基于继承而不是接口的...
动态代理主要分为两种:JDK代理和CGLIB代理。 **JDK代理**是基于接口的代理,它通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。当我们的目标对象实现了特定的接口时,我们可以...
本篇将详细探讨JDK动态代理和Cglib动态代理,并通过源码实例来加深理解。 首先,JDK动态代理是Java内置的一种机制,它依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类...