标签:java
可配置的AOP框架中两个重要的类:
BeanFactory
工厂类BeanFactory负责创建目标或代理类的实例对象,并通过配置文件进行切换,其getBean()方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean(根据本例子),则直接返回该类的实例对象,否则返回该类实例对象的getProxy()方法返回的对象。
BeanFactory的构造方法接收代表配置文件的输入流对象,配置文件格式:
#xxx=java.util.ArrayList 不是ProxyFactoryBean类
xxx=cn.test.ProxyFactoryBean
xxx.target=java.util.ArrayList #目标类。
xxx.advice=cn.test.Myadvice #系统方法类。对目标类添加自定义的方法
ProxyFactoryBean
充当封装生成动态代理的工厂,需要为工厂提供:
1.目标对象(target)
2.系统方法类对象(Advice)
编写客户端应用
1.编写实现Advice接口的类和在配置文件中进行配置
2.调用BeanFactory获取对象
代码实现
1.编写Advice接口类
/* * 系统功能的接口类 */ public interface Advice { void beforMethod(); // 在目标方法之前的系统功能方法(只传递目标方法method,可传递目标对象target,method,参数args) void afterMethod(Method method); // 在目标方法之后的系统功能方法 }
2.实现Advice接口
/* * 实现系统功能接口的类 */ public class MyAdvice implements Advice { private long startTime = 0; @Override public void beforMethod() { System.out.println("----调用目标方法之前的系统方法"); startTime = System.currentTimeMillis(); } @Override public void afterMethod(Method method) { System.out.println("----调用目标方法之后的系统方法"); long endTime = System.currentTimeMillis(); System.out .println(method.getName() + " 执行时间:" + (endTime - startTime)); } }
3.编写配置文件config.properties
#xxx=java.util.ArrayList xxx=com.test.aopframework.ProxyFactoryBean #实现Advice接口的类 xxx.advice=com.test.proxy.MyAdvice
#配置需要代理的目标类 xxx.target=java.util.ArrayList
4.BeanFactory类(创建目标类或代理类的实例对象)
/* * JavaBean类 */ public class BeanFactory { Properties props = new Properties(); // 配置.property文件,通过property取出值 public BeanFactory(InputStream ips) { try { props.load(ips); } catch (IOException e) { e.printStackTrace(); } } public Object getBean(String name) { String propertyName = props.getProperty(name); // 取出配置文件属性值 Object bean = null; try { Class clazz = Class.forName(propertyName); // 得到属性值的字节码 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((String) 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; } }
5.ProxyFactoryBean(充当封装生成动态代理的工厂)
/* * 充当封装生成动态代理的工厂 */ 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() { // 创建代理方法 return (Object) Proxy.newProxyInstance( target.getClass().getClassLoader(), // 实现的是和目标对象相同的类加载器 target.getClass().getInterfaces(), // 实现的是和目标对象相同的接口 new InvocationHandler() { @Override // proxy:代表代理的对象 method:代表代理对象调用的方法 args:代表调用方法接收的参数 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.beforMethod(); Object retVal = method.invoke(target, args); // 反射机制,调用目标对象target的方法 advice.afterMethod(method); // ////传递给目标target // return对象将返回给代理。可将值进行过滤 return retVal; } }); } }
6.编写客户端应用
/* * 编写客户端应用aop框架 */ public class ClientAopFrameWork { public static void main(String[] args) { InputStream ips = ClientAopFrameWork.class .getResourceAsStream("config.properties"); Object bean = new BeanFactory(ips).getBean("xxx"); System.out.println(bean); } }
标签:java
原文地址:http://blog.csdn.net/u010366796/article/details/44275889