无动态代理:
声明接口:
package com.lucas;
public interface HelloWord {
public void sayHello();
}
实现类:
package com.lucas;
import com.lucas.HelloWord;
public class HelloWorldImpl implements HelloWord{
public void sayHello() {
System.out.println("hello world!");
}
public static void main(String[] args) {
HelloWord helloWorld = new HelloWorldImpl();
helloWorld.sayHello();
}
}
jdk动态代理
package com.lucas;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyExample implements InvocationHandler {
/**
* 真实对象
*/
private Object target;
/**
* 建立代理对象和真实对象之间的代理关系
* @param target 真实对象
* @return 代理对象
*/
public Object bind(Object target) {
this.target = target;
/**
* 参数1:类加载器
* 参数2:把生成的动态代理类下挂到哪个接口下,这个写法就是下挂到target实现的接口下
* 参数3:定义实现方法逻辑的代理类,this表示当前对象,他必须实现InvocationHandler接口的invoke方法,它就是代理逻辑方法的实现方法
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
/**
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前的服务");
//相当于调用真实对象,只是通过反射实现而已
Object obj = method.invoke(target, args);
System.out.println("在调度真实对象之后的服务");
return obj;
}
public static void main(String[] args) {
JdkProxyExample jdk = new JdkProxyExample();
HelloWord proxy = (HelloWord)jdk.bind(new HelloWorldImpl());
proxy.sayHello();
}
}
获取代理类:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
需要classloader:他的作用,将生成的代理类加载jvm中执行--
需要接口interfaces:他的作用:具体实现类的接口,目的是为了让代理类和真实实现类实现的接口相同,方便代理
InvocationHandler:他的作用:映射invoke方法到接口中的方法--
proxy:相当于商务对象,target相当于软件工程师对象,bind方法就是建立商务和软件工程师代理关系的方法。invoke就是商务逻辑,调用商务逻辑就是调用软件工程师逻辑,从而实现代理的目的。
源码解读:
/**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler.
*
* <p>{@code Proxy.newProxyInstance} throws
* {@code IllegalArgumentException} for the same reasons that
* {@code Proxy.getProxyClass} does.
*
* @param loader the class loader to define the proxy class
* @param interfaces the list of interfaces for the proxy class
* to implement
* @param h the invocation handler to dispatch method invocations to
* @return a proxy instance with the specified invocation handler of a
* proxy class that is defined by the specified class loader
* and that implements the specified interfaces
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access;</li>
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to {@code intf};</li>
* <li> any of the given proxy interfaces is non-public and the
* caller class is not in the same {@linkplain Package runtime package}
* as the non-public interface and the invocation of
* {@link SecurityManager#checkPermission s.checkPermission} with
* {@code ReflectPermission("newProxyInPackage.{package name}")}
* permission denies access.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}, or
* if the invocation handler, {@code h}, is
* {@code null}
*/
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
1399

被折叠的 条评论
为什么被折叠?



