liangbizhi / blog Goto Github PK
View Code? Open in Web Editor NEW嗯……
嗯……
http://www.importnew.com/27772.html
假设我们有接口:
public interface Hello {
String sayHello(String name);
}
有其实现类:
public class HelloImpl implements Hello {
@Override
public String sayHello(String name) {
return "hello, " + name;
}
}
于是我们可以编写HelloImpl的静态代理类实现:
public class StaticHelloProxy extends HelloImpl {
private Hello hello = new HelloImpl();
@Override
public String sayHello(String name) {
System.out.println("before say hello");
return super.sayHello(name);
}
}
首先实现一个InvocationHandler,方法调用会被转发到该类的invoke()方法
public class HelloInvocationHandler implements InvocationHandler {
private Hello hello;
public HelloInvocationHandler(Hello hello) {
this.hello = hello;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("sayHello".equals(method.getName())) {
System.out.println("before invoke sayHello");
}
return method.invoke(hello, args);
}
}
接着通过JDK动态代理获取Hello的代理对象:
public class JdkDynamicMain {
public static void main(String[] args) {
Hello hello = (Hello) Proxy.newProxyInstance(
// 类加载器
JdkDynamicMain.class.getClassLoader(),
// 代理类需要实现的接口
new Class[]{Hello.class},
// 方法调用实际的处理者
new HelloInvocationHandler(new HelloImpl()));
System.out.println(hello.sayHello("bizhi"));
}
}
可以发现hello.getClass().getName()
:com.sun.proxy.$Proxy0
;
hello.getClass().getSuperclass().getName()
:java.lang.reflect.Proxy
;
的确是动态生成了类型。
缺点:只支持接口代理。
假设有一个类:
public class Hello {
public String sayHello(String name) {
return "hello: " + name;
}
}
首先实现一个MethodInterceptor
,方法调用会被转发到该类的intercept()方法。
public class HelloMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before invoke sayHello");
return methodProxy.invokeSuper(o, args);
}
}
测试一下:
public class HelloMethodInterceptorMain {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(new HelloMethodInterceptor());
Hello hello = (Hello) enhancer.create();
System.out.println(hello.sayHello("bizhi"));
}
}
将属性写进配置文件中classpath:/config/PlainObject.properties
中:
hello=你好
假设有普通类:
public class PlainObject {
}
封装的CGLIB类:
public class DynamicBean {
private Object object = null;
private BeanMap beanMap = null;
public DynamicBean(Map propertyMap) {
this.object = generateBean(propertyMap);
this.beanMap = BeanMap.create(this.object);
}
private Object generateBean(Map propertyMap) {
BeanGenerator generator = new BeanGenerator();
// 所有属性名
Set keySet = propertyMap.keySet();
for (Iterator iterator = keySet.iterator(); iterator.hasNext(); ) {
String key = (String) iterator.next();
generator.addProperty(key, (Class) propertyMap.get(key));
}
return generator.create();
}
public void setValue(Object property, Object value) {
beanMap.put(property, value);
}
public Object getValue(String property) {
return beanMap.get(property);
}
public Object getObject() {
return this.object;
}
}
从配置文件读取配置并添加到类中逻辑:
public class ClassUtil {
private static final String filePath = "/config/";
public static Object dynamicClass(Object object) throws Exception {
Map<String, Object> returnMap = new HashMap<>();
Map<String, Object> typeMap = new HashMap<>();
// 读取配置文件
Properties properties = new Properties();
String sourcepackage = object.getClass().getName();
String classname = sourcepackage.substring(sourcepackage.lastIndexOf(".") + 1);
InputStream in = ClassUtil.class.getResourceAsStream(filePath + classname + ".properties");
properties.load(in);
Set<String> keyList = properties.stringPropertyNames();
// 先读取对象原有属性
Class type = object.getClass();
BeanInfo beanInfo = Introspector.getBeanInfo(type);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (!"class".equals(propertyName)) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(object, new Object());
// 读取属性值
if (result != null) {
returnMap.put(propertyName, result);
} else {
returnMap.put(propertyName, "");
}
// 读取属性类型
typeMap.put(propertyName, descriptor.getPropertyType());
}
}
// 加载配置文件中的属性,即要添加的属性
Iterator<String> iterator = keyList.iterator();
while(iterator.hasNext()) {
String key = iterator.next();
returnMap.put(key, properties.getProperty(key));
typeMap.put(key, Class.forName("java.lang.String"));
}
// map转换成实体对象
DynamicBean bean = new DynamicBean(typeMap);
// 赋值
Set<String> keys = typeMap.keySet();
for (String key : keys) {
bean.setValue(key, returnMap.get(key));
}
Object obj = bean.getObject();
return obj;
}
}
测试类:
public class CGLibMain {
public static void main(String[] args) throws Exception {
PlainObject newObj = (PlainObject) ClassUtil.dynamicClass(new PlainObject());
System.out.println(newObj);
}
}
https://blog.csdn.net/ajun_studio/article/details/6807181
还有一种是通过JDK 6+的编译API把Java文件直接编译到内存的手段:
昔々から、僕は生れだ。
人生なんて、意味はまだ知らない。
そろそろいきましょうが。
間もなく、1番線に回り、福田方面行きが参ります。危ないですから、黄色線までお下がりください。
次は福田、福田です。お出口は左側です。地下鉄2番線お乗り換えです。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.