Constructor[] constructors = clazzProxy1.getConstructors(); //返回代理类里的所有构造方法
for(Constructor constructor : constructors){
String name = constructor.getName(); //返回构造方法的方法名
StringBuilder sBuilder = new StringBuilder(name); //由于不知道是不是有参的, 所以手动拼写代码
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes(); //返回构造方法的参数类型
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0) // 个人认为可以将这部放在前面先判断
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());//拼接成一个构造方法 xxx(xx);
//这里打印的结果是$Proxy0(java.lang.reflect.InvocationHandler)
//InvocationHandler 是每一个代理处理程序所实现的一个接口,
//也就是说代理要处理程序,就必须实现InvocationHandler接口
}
for(Method method : methods){
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
} //代码同构造方法 不做解释
创建代理的实例化对象 以Collection 为例
class MyInvocationHander1 implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander1());
//用代理获取实例对象必须传入InvocationHandlder接口,
//因为InvocationHandlder是调用处理程序实现的接口。
System.out.println(proxy1);
proxy1.clear();
// proxy1.size(); //有返回值的方法不能被成功调用,因为invoke方法返回的是null值
Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){ //匿名内部类写法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}); //同上 不解释
/*
代理类实现的三个步骤, 第一,必须是有代理类的目标实例对象。 第二,代理类的类加载器。 第三,代理类的实现接口
*/
Collection proxy3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(), //目标类的类加载器
new Class[]{Collection.class}, //目标类
new InvocationHandler(){
ArrayList target = new ArrayList();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("我是ArrayList的HashCode: "+target.hashCode());
Object retVal = method.invoke(target, args);
System.out.println(retVal.getClass().getName());
return retVal;
}
}
);
proxy3.add("zxx"); //每add一次就调用一次invoke方法
proxy3.add("lhm");
proxy3.add("bxd");
System.out.println(proxy3.size());
//System.out.println(proxy3.getClass().getName());());
//从object继承的方法只有hashCode equals toString派发给InvocationHandler去做。
为代理添加一些自定义的功能,那么,这个接口我们可以自定义,比如:计算方法的时间
首先需要一个接口。
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() {
// TODO Auto-generated method stub
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(), //目标的类加载器
target.getClass().getInterfaces(),//由于是代理, 一定有一个目标实现的接口, 至少一个
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.beforeMethod(method); //自定义接口的方法,
//这里的invoke,延续了代理类的方法,如果代理类调用了set方法, 那么
//在这里会继续将set方法引入给目标类使用
Object retVal = method.invoke(target, args);
advice.afterMethod(method); //自定义接口的方法
return retVal;
}
}
);
return proxy3;
}
}
AOP的定义
Spring框架里有一个AOP的概念, 所以的AOP,是面向切面的编程, 也就是说,在框架的基础上添加事物等一系列的功能。
根据配置文件获取到动态代理的例子:
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 proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){
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 proxy3;
}
public class BeanFactory {
Properties props = new Properties();
public BeanFactory(InputStream ips){
try {
props.load(ips); //读取配置文件
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getBean(String name){ //要获取到目标类的配置的名字
String className = props.getProperty(name);
Object bean = null;
try {
Class clazz = Class.forName(className); //生成一个实例, 如果这个实例是个代理类的话, 那么转入代理方法,
//如果不是,返回BEAN
bean = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
if(bean instanceof ProxyFactoryBean){
Object proxy = null;
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean; //先将目标类强转成代理类
try {
//然后获取到接口的实例
Advice advice = (Advice)Class.forName(props.getProperty(name + ".advice")).newInstance();
//获取目标类的实例
Object target = Class.forName(props.getProperty(name + ".target")).newInstance();
//在代理类里将接口与目标类作为变量传入, 所以这里只需要set就可以执行代理类里的方法
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
//执行代理类的方法,方法在上面
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
e.printStackTrace();
}
return proxy;
}
return bean;
}
}
------------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
详情请查看:http://edu.csdn.net/