美文网首页
读书笔记:架构探险 从零开始写javaweb框架-第四章

读书笔记:架构探险 从零开始写javaweb框架-第四章

作者: Hiwayz | 来源:发表于2018-09-14 15:51 被阅读14次

边看书边跟着敲代码,学着搭一个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

相关文章

网友评论

      本文标题:读书笔记:架构探险 从零开始写javaweb框架-第四章

      本文链接:https://www.haomeiwen.com/subject/xgvogftx.html