---------------------- android培训、java培训、期待与您交流! ----------------------
1.动态代理基础示例:
public class ProxyTest{
public static void main(String[] args) throws Exception {
// 生成Collection的代理类
Class clazzProxy1 = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
System.out.println("--------begin constructors list------");
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());
}
System.out.println("--------begin methods list----------");
Method[] methods = clazzProxy1.getMethods();
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());
}
System.out.println("----begin create instance object-----");
Constructor constructor = clazzProxy1
.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler {
//proxy:通过代理生成的对象;method:对象调用方法;args:方法接收的参数
public Object invoke(Object proxy, Method method,
Object[] args)throws Throwable {
return null;
}
}
Collection proxy1 = (Collection) constructor
.newInstance(new MyInvocationHander1());
System.out.println(proxy1);// 输出null;对象创建成功,toString返
//回的null。若对象未创建成功,会发生空指针异常。
proxy1.clear();
// proxy1.size();//此时不能调用有返回值的方法。通过下面代理类原理分析
//原因可以知道null不能转换成Integer类型。
// 用匿名内部类的方法创建代理对象
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 list=new ArrayList();
//proxy:通过代理生成的对象;method:对象调用方法;args:方法接收的参数
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
Object value=method.invoke(list,args);
return value;
}
});
// 生成的代理类代码,即代理原理
// $Proxy3 implements Collection{
// InvocationHandler handler;
// public $Proxy0(InvocationHandler handler){
// this.handler = handler;
// }
// //生成的Collection接口中的方法的运行原理
// int size(){
// return handler.invoke(this,this.getClass().getMethod("size"),null);
// }
// void clear(){
// handler.invoke(this,this.getClass().getMethod("clear"),null);
// }
// boolean add(Object obj){
// handler.invoke(this,this.getClass().getMethod("add"),obj);
// }
// }
proxy3.add("hhhh");
proxy3.add("dddd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());
//输出$Proxy0.原因:
//Proxy中,对于从Object中继承的方法,只有toString、equals、hashCode方发进//行了代理实现,其他的没有。
}
}
2.通过代理在原有方法上实现额外功能:
public interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}
以上方法定义一个公共接口,当要为某个类的方法增加额外功能时,只需要将代码块写在其实现类的实现方法中。
public class MyAdvice implements Advice {
long beginTime = 0;
public void afterMethod(Method method) {
System.out.println("从传智播客毕业上班啦!");
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of "
+ (endTime - beginTime));
}
public void beforeMethod(Method method) {
System.out.println("到传智播客来学习啦!");
beginTime = System.currentTimeMillis();
}
}
实现以上接口,把额外功能写在实现方法中。
public class Test {
public static void main(String[] a) {
final ArrayList target = new ArrayList();
Collection proxy3 = (Collection) getProxy(target,
new MyAdvice());
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());
}
private static Object getProxy(final Object target,
final Advice advice) {
Object proxy = Proxy.newProxyInstance(target.getClass()
.getClassLoader(),
/* new Class[]{Collection.class}, */
target.getClass().getInterfaces(),// 返回是实现接口的数组
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
advice.beforeMethod(method);
System.out.println("~~~代理对象原有 " +
method.getName()+ " 方法调用~~~");
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
System.out.println();
return retVal;
}
});
return proxy;
}
}
3.应用代理知识,通过配置文件方式为某个类增加额外功能:
配置文件:config.properties
#加载类,由此类父接口生成代理对象
#xxx=java.util.ArrayList
xxx=work.ProxyFactoryBean
#额外功能封装类
xxx.advice=proxy.MyAdvice
#实际目标对象类
xxx.target=java.util.ArrayList
Bean工厂类:
package work;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import proxy.Advice;
public class BeanFactory {
Properties props = new Properties();
public BeanFactory(InputStream ips){
try {
props.load(ips);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object getBean(String name){
//在实际项目中,name应该是一个bean类名
String className = props.getProperty(name);
Object bean = null;
try {
Class clazz = Class.forName(className);
bean = clazz.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
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();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return proxy;
}
return bean;
}
}
代理Bean工厂类:
package work;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import 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() {
// TODO Auto-generated method stub
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
/*new Class[]{Collection.class},*/
target.getClass().getInterfaces(),
new InvocationHandler(){
public Object invoke(Object proxy, Method method,
Object[] args)throws Throwable {
advice.beforeMethod(method);
System.out.println("代理类方法执行");
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal; }
}
);
return proxy3;
}
}
测试类:
package work;
import java.io.InputStream;
import java.util.Collection;
public class AopFrameworkTest {
public static void main(String[] args) throws Exception {
InputStream ips = AopFrameworkTest.class.
getResourceAsStream("config.properties");
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
((Collection)bean).clear();
}
}
注:Advice和MyAdvice类与23中的相同,位于proxy包中。
代码来自张老师基础加强视频讲解源码
---------------------- android培训、java培训、期待与您交流! ----------------------