边看书边跟着敲代码,学着搭一个springmvc的简单框架,代码我放在了GitHub上:
GitHub
代理模式以及AOP
接口:
public interface Hello {
void say(String name);
}
实现类:
public class HelloImpl implements Hello {
public void say(String name) {
System.out.println("Hello"+name);
}
}
静态代理:
public class HelloProxy implements Hello {
private Hello hello;
public HelloProxy(){
hello = new HelloImpl();
}
public void say(String name) {
before();
hello.say(name);
after();
}
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
public static void main(String[] args){
Hello helloProxy = new HelloProxy();
helloProxy.say("hiway");
}
}
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target,args);
after();
return result;
}
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
public <T> T getProxy(){
return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
public static void main(String[] args){
Hello helloProxy =new DynamicProxy(new HelloImpl()).getProxy();
helloProxy.say("hiway");
}
}
CGLib代理
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibDynamicProxy implements MethodInterceptor{
private static CGLibDynamicProxy instance = new CGLibDynamicProxy();
private CGLibDynamicProxy(){}
public static CGLibDynamicProxy getInstance(){
return instance;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls){
return (T) Enhancer.create(cls,this);
}
public Object intercept(Object target, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(target,params);
after();
return result;
}
private void before(){
System.out.println("before");
}
private void after(){
System.out.println("after");
}
}
Proxy类:代理接口类
ProxyChain类:代理链类
ProxyManager类,代理管理器类
AspectProxy类:切面代理类
AopHelper类:方法拦截助手类
ControllerAspect类:继承AspectProxy抽象类,实现拦截controller所有方法,标有注释@Aspect(Controller.class)
aop流程:
1.首先计算获取所有AspectProxy的并且含有@Aspect注解的子类
2.获取上一步子类的@Aspect注解里的value(例如ControllerAspect类中的Controller.class),并计算应用包下带有该value注解类的所有类
3.将上两步的结果放入Map中,Map<Class<?>,Set<Class<?>>> =(AspectProxy的子类,子类的@Aspect里的value里的这个注解类的所有类)=(ControllerAspect.class,所有带有@Controller注解的类)
4.遍历Map,遍历所有带有@Controller注解的类,然后将每个带有@controller的类放到key,value为AspectProxy的子类的实例(newInstance),结果意义上有点像上一步map的key,value互换。Map<Class<?>,List<Proxy>> = (带有@Controller注解的类,包含这个类的所有Aspect代理类)=(AController.class,List<>{ControllerAspect实例...})。value 大概表示这个类有哪些切面包含了它,在我们运行这个类的过程中要运行的Aspect拦截器
5.遍历第四步的Map,通过ProxyManager,生成一个AController的代理类,代理类会将List<Proxy>中的aop方法织入到Acontroller类的方法中。
6.最后将(AController.class,上一步生成的AController代理类)放入到BeanHelper中的Bean_Map中。这样通过ioc注入类的时候,就会使用生成好的aop代理类。
学习资料
CGLib Enhancer MethodInterceptor
https://www.cnblogs.com/shijiaqi1066/p/3429691.html
https://blog.csdn.net/jackyechina/article/details/53081438
网友评论