我们都知道spring的配置文件中可以进行声明式事务管理,其基于的原理是spring aop 切片编程,aop是基于动态代理的,动态代理可以从jvm加载类时通过反射对方法进行额外的处理。
1,先定义一个接口,把我们要做的事情写成接口方法
public interface IOstocy{
void sayHello(String name);
void sayGoodBye(String name);
}
2,我们给与IOstocy一个实现类
public class Ostocy implements IOstocy{
public void sayHello(String name){
System.out.println("hello"+name);
}
public void sayGoodBye(String name){
System.out.println(name+"goodsBye!");
}
}
3,定义一个接口,用来保存你需要对IOstocy逻辑进行额外处理的方法,例如记录sayHello的对象是谁
public interface IOperation{
void start(Method method);
void end(Method method);
}
定义了一个开始和结束接口方法,接下来需要给一个实现类
4,定义个实现类,去实现IOperation接口
public class LoggerOperation implements IOperation {
public void end(Method method) {
Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
}
public void start(Method method) {
Logger.logging(Level.INFO, method.getName() + " Method Start!");
}
}
5,要写一个代理类了,这个代理类,会把IOstocy和IOperation分开处理,IOstocy中的方法是很被动的,就呆着那里,等IOperation在他随便哪个位置进来。到底从前还是后进来,就要看你自己怎么处理了,这涉及到@after @before的实现原理了。
public class DynaProxyHello implements InvocationHandler {
/**
* 操作者
*/
private Object proxy;
/**
* 要处理的对象(也就是我们要在方法的前后加上业务逻辑的对象,如例子中的Hello)
*/
private Object delegate;
/**
* 动态生成方法被处理过后的对象 (写法固定)
*
* @param delegate
* @param proxy
* @return
*/
public Object bind(Object delegate,Object proxy) {
this.proxy = proxy;
this.delegate = delegate;
return Proxy.newProxyInstance(
this.delegate.getClass().getClassLoader(), this.delegate
.getClass().getInterfaces(), this);
}
/**
* 要处理的对象中的每个方法会被此方法送去JVM调用,也就是说,要处理的对象的方法只能通过此方法调用
* 此方法是动态的,不是手动调用的
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
try {
//反射得到操作者的实例
Class clazz = this.proxy.getClass();
//反射得到操作者的Start方法
Method start = clazz.getDeclaredMethod("start",
new Class[] { Method.class });
//反射执行start方法
start.invoke(this.proxy, new Object[] { method });
//执行要处理对象的原本方法
result = method.invoke(this.delegate, args);
// 反射得到操作者的end方法
Method end = clazz.getDeclaredMethod("end",
new Class[] { Method.class });
// 反射执行end方法
end.invoke(this.proxy, new Object[] { method });
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
6,测试下
public class Test {
public static void main(String[] args) {
IOstocy ostocy= (IOstocy)new DynaProxyHello().bind(new Ostocy(),new LoggerOperation());
ostocy.sayGoogBye("Double J");
ostocy.sayHello("Double J");
}
}
我的想法是在代理对象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上个if(),对传进来的method的名字进行判断,判断的条件存在XML里面.这样我们就可以配置文件时行解藕了.如果有兴趣的朋友可以把操作者,被代理者,都通过配置文件进行配置 ,那么就可以写一个简单的SpringAOP框架了.
谢谢 http://www.blogjava.net/DoubleJ/archive/2008/03/04/183796.html