黑马程序员_java基础加强_代理

---------------------- 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();

}

}

注:AdviceMyAdvice类与23中的相同,位于proxy包中。

代码来自张老师基础加强视频讲解源码




---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值