可配置的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);
}
}