需求:
实现一个类似spring的可配置的简单AOP框架;
通过配置文件可以指定程序是直接使用Bean 还是使用代理Bean
解决方案:
为实现代理我们需要一个目标类,也就是需要代理的Bean ,还需要有一个通告类,用来为Bean添加额外的操作
第一步:
编写一个代理Bean工厂类 ProxyBeanFactory ,制造一个代理Bean
package zhangweicong.aopFramework;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import zhangweiocng.autoProxy.Advice;
public class ProxyBeanFactory {
private Advice advice;
private Object target;
public void setAdvice(Advice advice) {
this.advice = advice;
}
public void setTarget(Object target) {
this.target = target;
}
public Advice getAdvice() {
return advice;
}
public Object getTarget() {
return target;
}
/**
* 由设置的Target类和Advice 类产生代理bean
* @return Objec 代理对象
*/
public Object getProxy(){
Object clazz = 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 returnValue =method.invoke(target, args);
System.out.println("--executeMethod--"+method.getName());
advice.afterMethod(method);
return returnValue;
}
}
);
return clazz;
}
}
第二部:
编写一个BeanFactory类 ,用于从配置文件加载一个Bean 或者是 代理Bean
package zhangweicong.aopFramework;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import zhangweiocng.autoProxy.Advice;
public class BeanFactory {
private Properties properties=new Properties();
public BeanFactory(InputStream inStream){
try {
properties.load(inStream);
} catch (IOException e) {
System.out.println("加载properties文件出错");
e.printStackTrace();
}
}
public Object getBean(String name){
String beanName = properties.getProperty(name);
Object bean=null;
try {
Class clazz = Class.forName(beanName);
bean=clazz.newInstance();
/*根据获取的类,判断要实现原Bean对象还是代理Bean对象
* */
if(bean instanceof ProxyBeanFactory){
ProxyBeanFactory proxyBeanFactory=(ProxyBeanFactory)bean ;
Advice advice=(Advice)Class.forName(properties.getProperty(name+".advice")).newInstance();
Object target=Class.forName(properties.getProperty(name+".target")).newInstance();
proxyBeanFactory.setAdvice(advice);
proxyBeanFactory.setTarget(target);
Object proxy = proxyBeanFactory.getProxy();
return proxy;
}
return bean;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
下面这个类是框架的用法
package zhangweicong.aopFramework;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
/**
* 对这个框架测试
* @author weicong
*
*/
public class aopFrameworkTest {
public static void main(String[] args) {
String fileName="config.properties";
InputStream inStream=null;
try{
inStream=new FileInputStream(fileName);
BeanFactory beanFactory =new BeanFactory(inStream);
Collection bean= (Collection )beanFactory.getBean("className");
bean.add("123");
bean.add("456");
System.out.println(bean.size());
}catch(IOException e){
System.out.println("读取文件出错");
e.printStackTrace();
}
}
}
配置文件内容
#className=java.util.ArrayList
className=zhangweicong.aopFramework.ProxyBeanFactory
className.target=java.util.ArrayList
className.advice=zhangweiocng.autoProxy.MyAdvice