高新代理( 三 )


直接在实现类中创建目标类的实例对象 , 可以看运行效果和加入日志代码 , 但没有实际意义 。
为实现类注入目标类的实例对象 , 不能采用匿名内部类的形式了 。
让匿名的实现类访问外面方法中的目标类实例对象的final类型的引用变量 。
将创建代理的过程改为一种更优雅的方式 , 重构出一个方法绑定接收目标同时返回代理对象 , 让调用者更懒惰 , 更方便 , 调用者甚至不用接触任何代理的API 。
将系统功能代码模块化 , 即将切面代码也改为通过参数形式提供 , 怎样把要执行的系统功能代码以参数形式提供?
把要执行的代码装到一个对象的某个方法里 , 然后把这个对象作为参数传递 , 接收者只要调用这个对象的方法 , 即等于执行了外界提供的代码!
为bind方法增加一个参数 。
图片:

高新代理

文章插图
实现AOP功能的封装与配置:
工厂类负责创建目标类或代理类的实例对象 , 并通过配置文件实现切换 。其方法根据参数
字符串返回一个相应的实例对象 , 如果参数字符串在配置文件中对应的类名不是 , 则
直接返回该类的实例对象 , 否则 , 返回该类实例对象的方法返回的对象 。
的构造方法接收代表配置文件的输入流对象 , 配置文件格式如下:
#xxx=java.util.
xxx=cn..
xxx.=java.util.
xxx.=cn..
充当封装生成动态代理的工厂 , 需要为工厂类提供哪些配置参数信息?
目标
通知
编写客户端应用:
编写实现接口的类和在配置文件中进行配置
调用获取对象
代码
************************配置文件****************************
#xxx=java.util.ArrayListxxx=cn.itcast.day03.aopframework.ProxyFactoryBeanxxx.advice=cn.itcast.day03.MyAdvicexxx.target=java.util.ArrayList
*****************************************************
package cn.itcast.day03.aopframework;import java.io.InputStream;import java.util.Collection;public class AopFrameworkTest {/*** @param args*/public static void main(String[] args) throws Exception {// TODO Auto-generated method stub//用相对路径getResourceAsStream来加载配置文件InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");//将ips流输出到BeanFactory类的构造方法中.并往getBean函数内传递XXX的键.Object bean = new BeanFactory(ips).getBean("xxx");//打印返回的值的名字.System.out.println(bean.getClass().getName());((Collection)bean).clear();}}
******************************************************
package cn.itcast.day03.aopframework;import java.io.IOException;import java.io.InputStream;import java.util.Properties;import cn.itcast.day03.Advice;public class BeanFactory {//建立Properties对象用于接收传进来的流.Properties props = new Properties();public BeanFactory(InputStream ips){try {//将AopFrameworkTest流中的数据传入到Properties中props.load(ips);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//将XXX的键传入到getBean中public Object getBean(String name){//获取XXX中的值String className = props.getProperty(name);//在try外边建立引用Object bean = null;try {//用Class.forName获取XXX中的字节码文件并用newInstance创建实例对象Class clazz = Class.forName(className);bean = clazz.newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} //对XXX中的值进行判断.是否实例化ProxyFactoryBean,如果不是直接返回到AopFrameworkTest并打印if(bean instanceof ProxyFactoryBean){//try外部建立引用Object proxy = null;//已知XXX的值肯定是ProxyFactoryBean的实力对象了.直接强转过来.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中的advice和target,proxyFactoryBean.setAdvice(advice);proxyFactoryBean.setTarget(target);//使用代理.proxy = proxyFactoryBean.getProxy();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//返回代理return proxy;}return bean;}}