这是张孝祥老师Java进阶讲解中最后一个视频,就是实现类似spring中的AOP的封装和配置,特别特别小型的一个框架雏形,但是spring中的核心思想还是体现出来了,真的厉害,张老师!!!
一、重点知识点
1、工厂类BeanFactory负责创建目标类或者是代理类的实例对象,并通过配置文件实现切换,其getBean()方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该实例对象的getProxy()方法返回的对象
2、BeanFactory的构造方法接收代表配置文件的输入流
3、ProxyFactoryBean充当封装生成动态代理的工厂,需要为工厂类提供目标、通知等参数信息
4、编写测试类进行测试
二、代码实现
整体代码结构:
代码实现:
1、通知接口以及实现类
1 package com.ssc.proxy; 2 3 import java.lang.reflect.Method; 4 5 public interface Advice { 6 7 void beforeMethod(Method method); 8 void afterMethod(Method method); 9 10 } 11 12 --------------------------------------------------------------------------- 13 14 package com.ssc.proxy; 15 16 import java.lang.reflect.Method; 17 18 public class MyAdvice implements Advice { 19 20 long beginTime = 0; 21 long endTime = 0; 22 23 @Override 24 public void beforeMethod(Method method) { 25 System.out.println("Advice中的方法开始执行了。。。"); 26 beginTime = System.currentTimeMillis(); 27 } 28 29 @Override 30 public void afterMethod(Method method) { 31 endTime = System.currentTimeMillis(); 32 System.out.println(method.getName() + "running time:" + (endTime - beginTime)); 33 System.out.println("Advice中的方法结束执行了。。。"); 34 } 35 36 }
2、BeanFactory实现
1 package com.ssc.aopframework; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Properties; 6 7 import com.ssc.proxy.Advice; 8 9 public class BeanFactory { 10 11 Properties props = new Properties(); 12 13 public BeanFactory(InputStream ips){ 14 try { 15 props.load(ips); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 } 20 21 public Object getBean(String name){ 22 String className = props.getProperty(name); 23 Object bean = null; 24 try { 25 Class clazz = Class.forName(className); 26 bean = clazz.newInstance(); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 if(bean instanceof ProxyFactoryBean){ 31 Object proxy = null; 32 ProxyFactoryBean proxyBeanFactory = (ProxyFactoryBean) bean; 33 try { 34 // 从配置文件中读取类名,通过反射创建对象参数 35 Advice advice = (Advice) Class.forName(props.getProperty(name + ".advice")).newInstance(); 36 Object target = Class.forName(props.getProperty(name + ".target")).newInstance(); 37 // 初始化通知以及目标参数 38 proxyBeanFactory.setAdvice(advice); 39 proxyBeanFactory.setTarget(target); 40 proxy = proxyBeanFactory.getProxy(); 41 return proxy; 42 } catch (Exception e) { 43 e.printStackTrace(); 44 } 45 } 46 return bean; 47 } 48 }
3、ProxyFactoryBean 实现
1 package com.ssc.aopframework; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 import com.ssc.proxy.Advice; 8 9 public class ProxyFactoryBean { 10 11 private Advice advice; 12 13 private Object target; 14 15 public Object getProxy() { 16 Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass() 17 .getInterfaces(), new InvocationHandler() { 18 19 @Override 20 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 21 22 // 这里就是Collection类或者是子类中的方法执行 也就是调用了add()方法 同时我还做了一些其他事情。计算程序运行时间 23 advice.beforeMethod(method); 24 Object retVal = method.invoke(target, args); 25 advice.afterMethod(method); 26 27 return retVal; 28 } 29 }); 30 return proxy; 31 } 32 33 public Advice getAdvice() { 34 return advice; 35 } 36 37 public void setAdvice(Advice advice) { 38 this.advice = advice; 39 } 40 41 public Object getTarget() { 42 return target; 43 } 44 45 public void setTarget(Object target) { 46 this.target = target; 47 } 48 49 }
4、配置文件实现(纯粹瞎写的配置文件)
1 #xxx=java.util.ArrayList 2 xxx=com.ssc.aopframework.ProxyFactoryBean 3 xxx.advice=com.ssc.proxy.MyAdvice 4 xxx.target=java.util.ArrayList
5、测试类实现
1 package com.ssc.aopframework; 2 3 import java.io.InputStream; 4 5 public class AopFrameworkTest { 6 7 public static void main(String[] args) { 8 InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties"); 9 Object bean = new BeanFactory(ips).getBean("xxx"); 10 System.out.println(bean.getClass().getName()); 11 } 12 }