Java动态代理-实现类似spring的可配置的AOP框架

  • 工厂类BeanFactory负责创建目标类或者代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的getProxy方法返回的对象
  • BeanFactory的构造方法结婚搜代表配置文件的输入流对象,配置文件格式如下:
    • #xxx=java.util.ArrayList
    • xxx=com.mari.proxy.aopframework.ProxyFactoryBean
    • xxx.advice=com.mari.proxy.MyAdvice
    • xxx.target=java.util.ArrayList
  • ProxyFactoryBen充当封装生成动态代理的工厂,需要2个参数配置信息:
    • 目标
    • 通知

BeanFactory.java

package com.mari.proxy.aopframework;

import java.io.InputStream;
import java.util.Properties;

import com.mari.proxy.Advice;

public class BeanFactory {

  Properties props = new Properties();

  public BeanFactory(InputStream ips){
    try {
      props.load(ips);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  public Object getBean(String name){
    String className = props.getProperty(name);
    Object bean = null;
    try {
      Class clazz = Class.forName(className);
      bean = clazz.newInstance();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    if (bean instanceof ProxyFactoryBean) {
      Object proxy = null;
      try {
        ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) bean;
        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) {
        e.printStackTrace();
      }
      return proxy;
    }
    return bean;
  }

}

ProxyFactoryBean.java

package com.mari.proxy.aopframework;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.mari.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(){

    Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                                           target.getClass().getInterfaces(), 
                                           new InvocationHandler() {


      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

         advice.beforeMethod(method);
          Object rctVal = method.invoke(target, args);
          advice.afterMethod(method);

          return rctVal;

      }
    });
    return proxy;
  }


}

Advice.java和MyAdvice.java在上一篇博客中已经贴出来了。大家可以去Java代理学习-创建动态类的实例对象及调用其方法看下。


测试类:AopFrameworkTest.java

package com.mari.proxy.aopframework;

import java.io.InputStream;
import java.util.Collection;

public class AopFrameworkTest {


    InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");

    Object bean = new BeanFactory(ips).getBean("xxx");

    System.out.println(bean.getClass().getName());

    Collection collection = (Collection)bean;

    collection.add("a");
    collection.add("b");
    collection.add("c");

    System.out.println(collection.size());

    System.out.println("-----------------------------");

    for (Object object : collection) {
      System.out.println(object);
    }

  }

}

控制台的输出

com.sun.proxy.$Proxy0
add, running time of 1
add, running time of 0
add, running time of 0
size, running time of 0
3
-----------------------------
iterator, running time of 0
a
b
c

好了,到这里java代理的学习就告一段落了,接下来有时间的话会进行:
java类加载器,及其委托机制的深入学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值