一. JdkProxy
jdkproxy动态代理必须基于接口(interface)实现
- 接口
UserInterface.java
public interface UserService {
String getUserName(String userCde);
}
- 原始实现类:
UseServiceImpl.java
public class UserSer服务器托管网viceImpl implements UserSerice {
@Override
public String getUserName(String userCde) {
System.out.println("the name of " + userCde + "is Austin");
return "Austin";
}
}
- 代理类 :
UserProxyFactoryBJdk.java
public class UserProxyFactoryBJdk {
public static UserService getUserServiceProxy(服务器托管网UserService origin) {
UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader()
, new Class[]{UserService.class}
, new InvocationHandler() { //动态代理实现类
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object o = method.invoke(origin, args);
System.out.println("after");
return o;
}
});
return userService;
}
public static void main(String[] args) {
UserService userService = getUserServiceProxy(new UserServiceImpl());
userService.getUserName("123");
}
}
执行结果:
before
the name of 123is Austin
after
二. Cglib动态代理
Cglib实现动态代理与JdkProxy不同, 是通过构建继承类实现
- 原始类
UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
@Override
public String getUserName(String userCde) {
System.out.println("the name of " + userCde + "is Austin");
return "Austin";
}
}
- 代理类 :
UserProxyFactoryByCglib.java
public static UserServiceImpl getUserServiceProxy(UserService origin) {
Enhancer enhancer = new Enhancer();
// 设置debug信息
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY
, "/home/aa/dev/testfile/com/austin/meta/cxf/");
// 设置父类:UserServiceImpl
enhancer.setSuperclass(UserServiceImpl.class);
//设置代理实现逻辑
enhancer.setCallback(new CglibInterCeptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CglibInterCeptor.intercept-before");
Object o = proxy.invokeSuper(obj, args);
System.out.println("CglibInterCeptor.intercept-after");
return o;
}
});
UserServiceImpl userService = ((UserServiceImpl) enhancer.create());
return userService;
}
public static void main(String[] args) {
UserService userService = getUserServiceProxy(new UserServiceImpl());
userService.getUserName("123");
}
- 执行结果
CglibInterCeptor.intercept-before
the name of 123is Austin
CglibInterCeptor.intercept-after
三. Java动态编译
通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac-d 命令进行编译
- 需要动态编译的类文件
package com.austin.meta.dynamiccompiler;
public class UserServiceImplE extends UserServiceImpl {
public UserServiceImplE() {
}
public String getUserName(String userCde) {
System.out.println("before");
super.getUserName(userCde);
System.out.println("after");
return "Austin";
}
}
- 动态编译类
public class JavaCompilerTest {
private static String basePath = "";
public static void main(String[] args) throws Exception{
System.out.println(ClassLoader.getSystemResource(""));
Class> userServiceImplE = compiler("UserServiceImplE");
UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);
o.getUserName("235");
}
private static Class> getClass(String pakcge, String className) {
Class> clazz = null;
try {
clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return clazz;
}
/**
* 动态编译java类,并通加载到JVM
*/
private static Class> compiler(String className) throws IOException {
File javaSrcFile = new File(basePath+ "/" + className + ".java");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
List options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());
JavaCompiler.CompilationTask task = compiler.getTask(null
, standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));
Boolean isCompilerSuccess = task.call();
if(!isCompilerSuccess) {
return null;
}
Class> clazz = getClass("com.austin.meta.dynamiccompiler", className);
return clazz;
}
}
- 执行结果
before
the name of 235is Austin
after
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: Vue源码学习(九):响应式前置:实现对象的依赖收集(dep和watcher)
好家伙,这是目前为止最绕的一章,也是十分抽象的一章 由于实在太过抽象,我只能用一个不那么抽象的实例去说服我自己 完整代码已开源https://github.com/Fattiger4399/analytic-vue.git 1.我们要做什么? 来看这个例子, …