代理的概念和作用
2014-05-05 20:03
169 查看
概念
Ø 要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如:异常处理,日志、事务管理、等
Ø 编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码
Ø 如果采用工程模式和配置文件的方法进行管理,则不需要修改客户端程序,在配置文件中配置使用目标类还是代理类,这样很容易切换,
生成代理类
方法一:InvocationHandler handler = new MyInvocationHandler(...);
//得到代理类的字节码对象
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
//先得到 该字节码的构造函数,然后通过构造函数 实例化一个对象
Foo f = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] { handler });
方法二:通过Proxy.newProxyInstance() 静态方法
Foo f = (Foo) Proxy.newProxyInstance(
Foo.class.getClassLoader(),//类加载器
new Class[] { Foo.class },//接口的字节码对象
handler);//必要的 参数
综合上面的可以生成一个万能的接口代理方法
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() {//参数三
/**
* proxyCol.add("adf"); 以此为例
* @proxy代理对象 proxyCol
* @method 代理对象调用的方法
* @args代理对象调用的方法,传递的参数
*/
@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;
}
Collection arr = new ArrayList();
Collection proxyCol = (Collection)getProxy(arr,new MyAdvice());
proxyCol.add("adf");
需要注意的地方:
System.out.println(proxyCol.getClass().getName());//得到的结果是$Proxy1 或者类似这样的,反正不算目标类(Collection ),原因如下:
getClass()方法是从Object对象上继承过来的,hashCode、equals 或 toString 也都是从Object类中继承来的,但只有这三个方法交给了Handler去处理,其他的方法都不交给Handler处理。
简单的aop框架
BeanFactory 类
public class BeanFactory { Properties props = new Properties(); /** * 加载配置文件信息 * @param in */ public BeanFactory(InputStream in){ try { props.load(in); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object getBean(String name){ Object bean = null; try { String className = props.getProperty(name); Class clazz = Class.forName(className); bean =clazz.newInstance(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(bean instanceof ProxyFactoryBean){ ProxyFactoryBean proxy = (ProxyFactoryBean)bean; try { Advice advice = (Advice)(Class.forName(props.getProperty(name+".advice")).newInstance()); Object target= (Object)(Class.forName(props.getProperty(name+".target")).newInstance()); proxy.setAdvice(advice); proxy.setTarget(target); bean= proxy.getProxy(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return bean; } }
ProxyFactoryBean 类
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() { Object proxy= Proxy.newProxyInstance( target.getClass().getClassLoader(),//目标对象(一般都是接口的实现类) /*new Class[]{Collection.class}*/ target.getClass().getInterfaces(), //目标对象的接口 new InvocationHandler() { /** * proxyCol.add("adf"); 以此为例 * @proxy 代理对象 proxyCol * @method 代理对象调用的方法 * @args 代理对象调用的方法,传递的参数 */ @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类
public class AopFrameworkTest { public static void main(String[] args) { testMyAopFramework(); } public static void testMyAopFramework(){ try { InputStream in = AopFrameworkTest.class.getResourceAsStream("conf.properties"); BeanFactory beanFac = new BeanFactory(in); Object obj =beanFac.getBean("xxx"); System.out.println(obj.getClass().getName());//打印类名称 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
相关文章推荐
- Java代理的概念与作用
- 【Java进阶-Java动态代理与AOP】01 代理类的作用与原理及AOP概念
- 代理的概念与作用
- 加强2注解。泛型。类加载器及其委托机制。代理的概念与作用原理,AOP概念。实现AOP功能的封装与配置。类似Spring。
- 动态与代理AOP--01【代理的作用与概念】【动态代理与AOP】
- "黑马程序员"代理的概念、作用
- 黑马程序员--09.动态与代理AOP--01【代理的作用与概念】【动态代理与AOP】
- 0103 Java设计模式03-动态代理(概念篇)【进阶】
- 【+】Maven介绍:包括作用、核心概念、用法、常用命令、扩展及配置
- PO BO VO DTO POJO DAO 概念及其作用
- PO BO VO DTO POJO DAO概念及其作用(附转换图)
- PO BO VO DTO POJO DAO概念及其作用(附转换图)
- iphone开发中,委托、代理、协议、数据源等几个重要概念
- JavaScript的作用域和块级作用域概念理解
- JavaScript的作用域和块级作用域概念理解
- PO BO VO DTO POJO DAO概念及其作用
- 疯狂Java学习笔记(33)----------java集合概念和作用
- spring学习(六)—AOP的概念和作用
- 不同作用域(scope)的Spring Bean之间的依赖关系的动态代理注入
- Mac OS开发中,委托、代理、协议、数据源等几个重要概念