- 工厂类BeanFactory负责创建目标类或者代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的getProxy方法返回的对象
- BeanFactory的构造方法结婚搜代表配置文件的输入流对象,配置文件格式如下:
- #xxx=java.util.ArrayList
- xxx=com.mari.proxy.aopframework.ProxyFactoryBean
- xxx.advice=com.mari.proxy.MyAdvice
- xxx.target=java.util.ArrayList
- ProxyFactoryBen充当封装生成动态代理的工厂,需要2个参数配置信息:
- 目标
- 通知
BeanFactory.java
package com.mari.proxy.aopframework;
import java.io.InputStream;
import java.util.Properties;
import com.mari.proxy.Advice;
public class BeanFactory {
Properties props = new Properties();
public BeanFactory(InputStream ips){
try {
props.load(ips);
}
catch (Exception e) {
e.printStackTrace();
}
}
public Object getBean(String name){
String className = props.getProperty(name);
Object bean = null;
try {
Class clazz = Class.forName(className);
bean = clazz.newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
if (bean instanceof ProxyFactoryBean) {
Object proxy = null;
try {
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) bean;
Advice advice = (Advice) Class.forName(props.getProperty(name + ".advice")).newInstance();
Object target = Class.forName(props.getProperty(name + ".target")).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
proxy = proxyFactoryBean.getProxy();
}
catch (Exception e) {
e.printStackTrace();
}
return proxy;
}
return bean;
}
}
ProxyFactoryBean.java
package com.mari.proxy.aopframework;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mari.proxy.Advice;
public class ProxyFactoryBean {
private Advice advice;
private Object target;
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
advice.beforeMethod(method);
Object rctVal = method.invoke(target, args);
advice.afterMethod(method);
return rctVal;
}
});
return proxy;
}
}
Advice.java和MyAdvice.java在上一篇博客中已经贴出来了。大家可以去Java代理学习-创建动态类的实例对象及调用其方法看下。
测试类:AopFrameworkTest.java
package com.mari.proxy.aopframework;
import java.io.InputStream;
import java.util.Collection;
public class AopFrameworkTest {
InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
Collection collection = (Collection)bean;
collection.add("a");
collection.add("b");
collection.add("c");
System.out.println(collection.size());
System.out.println("-----------------------------");
for (Object object : collection) {
System.out.println(object);
}
}
}
控制台的输出
com.sun.proxy.$Proxy0
add, running time of 1
add, running time of 0
add, running time of 0
size, running time of 0
3
-----------------------------
iterator, running time of 0
a
b
c
好了,到这里java代理的学习就告一段落了,接下来有时间的话会进行:
java类加载器,及其委托机制的深入学习