Spring版本:Spring 5.3.13-release
# 1、ObjectFactory
ObjectFactory
@FunctionalInterface public interface ObjectFactory{ T getObject() throws BeansException; }
ObjectFactory
ObjectFactory
看到这个方法,有种似曾相识的感觉,没错在FactoryBean
# 2、FactoryBean
FactoryBean
public interface FactoryBean{ String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable T getObject() throws Exception; @Nullable Class> getObjectType(); default boolean isSingleton() { return true; } }
如果不了解FactoryBean
# 3、ObjectFactory
ObjectFactory
# 4、ObjectFactory
FactoryBean
在获取FactoryBean
ObjectFactory
Scope接口中的get()方法:
public interface Scope {
// 省略部分源码
Object get(String name, ObjectFactory> objectFactory);
// 省略部分源码
}
这个方法主要的目的就是从对应的域中获取到指定名称的对象,而ObjectFactory>主要是为了自定义的域提供顶级拓展,而不是只仅限于request、response或者session等域。
ConfigurableListableBeanFactory#registerResolvableDependency()方法:
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
// 省略部分源码
void registerResolvableDependency(Class> dependencyType, @Nullable Object autowiredValue);
// 省略部分源码
}
这个方法看似与ObjectFactory
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
// 手动注入各种经过 ObjectFactory 代理的类, 以保证线程安全
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
上面就有使用ConfigurableListableBeanFactory#registerResolvableDependency()方法将ObjectFactory
ResponseObjectFactory源码:
private static class ResponseObjectFactory implements ObjectFactory, Serializable { @Override public ServletResponse getObject() { ServletResponse response = currentRequestAttributes().getResponse(); if (response == null) { throw new IllegalStateException("Current servlet response not available - " + "consider using RequestContextFilter instead of RequestContextListener"); } return response; } @Override public String toString() { return "Current HttpServletResponse"; } }
当开发者在某一个类中需要注入ServletResponse对象时,并不会直接创建一个ServletResponse对象进行注入,而是注入一个代理类,该代理类中的方法是通过ObjectFactoryDelegatingInvocationHandler实现的。这里需要注意的是ResponseObjectFactory类中的getObject()方法是从当前线程中去获取的ServletResponse,所以这里获取的ServletResponse是线程安全的。
AutowireUtils#ObjectFactoryDelegatingInvocationHandler源码:
private static class ObjectFactoryDelegatingInvocationHandler implements InvocationHandler, Serializable {
private final ObjectFactory> objectFactory;
ObjectFactoryDelegatingInvocationHandler(ObjectFactory> objectFactory) {
this.objectFactory = objectFactory;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "equals":
// only consider equal when proxies are identical.
return (proxy == args[0]);
case "hashCode":
// Use hashCode of proxy.
return System.identityHashCode(proxy);
case "toString":
return this.objectFactory.toString();
}
try {
return method.invoke(this.objectFactory.getObject(), args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
可以看到ObjectFactoryDelegatingInvocationHandler内部会持有一个ObjectFactory>,也就是刚刚说的ResponseObjectFactory。并且会调用ObjectFactory>#getObject()方法获取对象并将其进行注入,也就是上面ResponseObjectFactory类中的getObject()方法。所以开发者可以直接在类中注入HttpServletResponse并且保证线程安全。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-framework-v5.3.13
备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。
更多Java技术笔记可扫码关注下方微信公众号。



