首先,我们来定义一个Bean工厂【BeanFactory.java】
package com.java.aopframework;
import java.io.*;
import java.util.Properties;
import com.java.day3.Advice;
//这个类是纯粹地去创建一个JavaBean
public class BeanFactory {
Properties properties = new Properties();
//利用配置文件构造
public BeanFactory(InputStream ips)
{
try {
properties.load(ips);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public Object getBean(String name)
{
//System.out.println(""+name);
//c从配置文件中获取类名称
String className = properties.getProperty(name); //com.java.aopframework.ProxyFactoryBean
Class clazz = null;
Object bean = null;
System.out.println(""+className);
try {
//获取类名称
clazz = Class.forName(className);
System.out.println(""+clazz);
//获取javaBean,【注意】JavaBean必须要有一个不带参数的构造函数
bean = clazz.newInstance();
//如果是这种类型的JavaBean
if (bean instanceof ProxyFactoryBean)
{
//如果已经存在这个类, 就去获取代理
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
//Advice advice = ((Advice) properties.get(name+".advice")).getClass().newInstance();
//Object target = ((Object) properties.get(name+".target")).getClass().newInstance();
System.out.println(properties.getProperty(name+".advice")); //com.java.day3.MyAdvice
System.out.println(properties.getProperty(name+".target")); //java.util.ArrayList
String s_advice = properties.getProperty(name+".advice");
String s_target = properties.getProperty(name+".target");
Advice advice = (Advice) Class.forName(s_advice).newInstance();
Object target = (Object)Class.forName(s_target).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
Object proxy = proxyFactoryBean.getProxy();
//System.out.println(properties.getProperty(name+".advice")+"\t"+properties.get(name+".target")+"\t"+proxy);
return proxy;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//返回目标
return bean;
}
}
然后,再来一个代理Bean工厂
【ProxyFactoryBean.java】
package com.java.aopframework;
import java.lang.reflect.*;
import com.java.day3.Advice;
public class ProxyFactoryBean {
// 定义两个私有变量
private Object target;
private Advice advice;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
public Object getProxy() {
// TODO Auto-generated method stub
// 直接创建动态类及其实例对象
Object proxy = Proxy.newProxyInstance(target.getClass()
.getClassLoader(),
/* new Class { Collection.class }, */
target.getClass().getInterfaces(), new InvocationHandler() {
// 这也是匿名内部类
@Override
public Object invoke(Object proxy, Method method, Object args)
throws Throwable {
// 使用一个新对象来实现方法
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
});
return proxy;
}
}
再来一个测试类
【AopFrameWorkTest.java】
package com.java.aopframework;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
public class AopFrameWorkTest {
public static void main(String args) {
InputStream ips = AopFrameWorkTest.class.getResourceAsStream("configure.properties");
Object bean = new BeanFactory(ips).getBean("XXX");
//class com.sun.proxy.$Proxy0 com.sun.proxy.$Proxy0
System.out.println(bean.getClass()+"\t"+bean.getClass().getName());
ArrayList arrlist = (ArrayList)bean;
arrlist.add(10);
arrlist.add(50);
System.out.println(arrlist.size());
}
}
定义我的配置文件
【configure.properties】
XXX=java.util.ArrayList
#XXX= com.java.aopframework.ProxyFactoryBean
XXX.advice= com.java.day3.MyAdvice
XXX.target=java.util.ArrayList
总结
一个典型的动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class{...});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))
评论
填写昵称与邮箱即可评论,无需登录。