JDK动态代理
package com.xzp.active;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.cglib.proxy.Enhancer;
public class TransactionManageAdvice<T> implements InvocationHandler{
T target;// 被代理的真实对象
public void setTarget(T target) {
this.target = target;
}
public <T> T getProxy() {
return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("增强了");
//===================================================
method.invoke(target, args);
//===================================================
System.out.println("后置增强");
return null;
}
}
底层源码:
package com.xzp.active;
import com.xzp.pojo.User;
import com.xzp.service.UserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class UserServiceProxy extends Proxy implements UserService
{
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.xzp.service.UserService").getMethod("update", new Class[] { Class.forName("com.xzp.pojo.User") });
m4 = Class.forName("com.xzp.service.UserService").getMethod("save", new Class[] { Class.forName("com.xzp.pojo.User") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
}
catch (Exception localNoSuchMethodException)
{
}
}
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m4;
private static Method m0;
public UserServiceProxy(InvocationHandler paramInvocationHandler)
{
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void update(User paramUser)
{
try
{
this.h.invoke(this, m3, new Object[] { paramUser });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void save(User paramUser)
{
try
{
this.h.invoke(this, m4, new Object[] { paramUser });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
}
底层源码生成方式:
(通过ProxyGenerator类中的generateProxyClass方法指定真实对象的Class以及代理类名称来返回一个byte数组 将byte数组写入指定文件)
package com.xzp.active;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import com.xzp.service.impl.UserServiceImpl;
import sun.misc.ProxyGenerator;
public class Main {
public static void main(String[] args) {
generateClassFile(UserServiceImpl.class, "UserServiceProxy");
}
public static void generateClassFile(Class targetClass,String proxyName) {
byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, targetClass.getInterfaces());
String path = targetClass.getResource(".").getPath();
FileOutputStream out = null;
try {
out = new FileOutputStream(path + proxyName + ".class");
out.write(classFile);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(path);
}
}