在公司没事干了,学习下动态代理模式(关于代理的基础只是有很多帖子都有我就不重复了),做了个注解动态代理的例子,给那些学习注解或动态代理的初学者。
花了将近1小时,没做个什么优化,大牛勿喷。
几个主要的类:
注解类:
package test2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ProxyTag {
public Class proxyClass();
}
代理类父类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public abstract class ProxyBean implements InvocationHandler{
private Object o;
private String methodName;
public Object bind(Object obj,String methodName){
this.o = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] obj)
throws Throwable {
if(method.getName().equals(methodName)){
this.before();
Object result = method.invoke(o, obj);
this.after();
return result;
}else{
Object result = method.invoke(o, obj);
return result;
}
}
public abstract void before();
public abstract void after();
}
代理工厂:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ProxyFactory {
public static <T> T getProxyBean(Class<T> clazz){
T t = (T) newInstance(clazz);
Method[] methods = clazz.getMethods();
for(int i=0;i<methods.length;i++){
ProxyTag pt = methods[i].getAnnotation(ProxyTag.class);
if(pt == null){
continue;
}
ProxyBean pb = (ProxyBean) newInstance(pt.proxyClass());
t = (T) pb.bind(t, methods[i].getName());
}
return t;
}
private static Object newInstance(final Class clazz){
try {
Constructor cons = clazz.getConstructor();
return cons.newInstance(new Class[]{});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
测试类:
package test2;
public class ProxyClass extends ProxyBean{
public void after() {
System.out.println("after....");
}
public void before() {
System.out.println("before....");
}
}
public class ProxyClass2 extends ProxyBean{
public void after() {
System.out.println("after2....");
}
public void before() {
System.out.println("before2....");
}
}
public interface IDemo {
public void sayHello();
public void sayHello2();
}
public class Demo implements IDemo{
@ProxyTag(proxyClass=ProxyClass.class)
public void sayHello(){
System.out.println("hello....");
}
@ProxyTag(proxyClass=ProxyClass2.class)
public void sayHello2(){
System.out.println("hello2....");
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
IDemo demo = ProxyFactory.getProxyBean(Demo.class);
demo.sayHello();
System.out.println("-----------------------------");
demo.sayHello2();
}
}
before....
hello....
after....
-----------------------------
before2....
hello2....
after2....
我没有看过spring的拦截器源码,不过实现原理上估计差不多,需要源码请下载附件
刚刚发现代码有点笔误的地方,容易让人误解,展示的代码已经修改过来了,附件里的代码请自己对照着修改一下