一冬殃、前言
阿里巴巴長期招聘Java研發(fā)工程師p6,p7,p8等上不封頂級(jí)別滔迈,有意向的可以發(fā)簡(jiǎn)歷給我,注明想去的部門和工作地點(diǎn):1064454834@qq.com_
web.xml里面配置
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
component-bean.xml里面配置
<bean id="lavaPvgInfo" class="com.alibaba.lava.privilege.PrivilegeInfo"
scope="request">
<property name="aesKey" value="666" />
<aop:scoped-proxy />
</bean>
測(cè)試Rpc
@WebResource("/testService")
public class TestRpc {
@Autowired
private PrivilegeInfo pvgInfo;
@ResourceMapping("test")
public ActionResult test(ErrorContext context) {
ActionResult result = new ActionResult();
String aseKey = pvgInfo.getAesKey();
pvgInfo.setAesKey("888");
System.out.println("aseKey---" + aseKey);
return result;
}
}
二、源碼分析
2.1 使用裝飾模式對(duì)Bean定義進(jìn)行修改
先上時(shí)序圖:
可知上面時(shí)序圖完成了對(duì)RequestScope對(duì)象定義的修改創(chuàng)建了代理bean烂斋,具體修改內(nèi)容是修改了beanClass為ScopedProxyFactoryBean辽俗,并且保存了原來的bean定義originatingBeanDefinition。
下面看下主要代碼ScopedProxyUtils中的createScopedProxy
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
BeanDefinitionRegistry registry, boolean proxyTargetClass) {
String originalBeanName = definition.getBeanName();
BeanDefinition targetDefinition = definition.getBeanDefinition();
// 保持原來的beanName不變拴魄,但是基于原來的bean定義創(chuàng)建代理bean定義,
// 保存原來的bean定義到代理bean里面為后面創(chuàng)建代理類做準(zhǔn)備.
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
proxyDefinition.setSource(definition.getSource());
proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String targetBeanName = getTargetBeanName(originalBeanName);
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// ScopedFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
}
else {
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
}
// Copy autowire settings from original bean definition.
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
proxyDefinition.setPrimary(targetDefinition.isPrimary());
if (targetDefinition instanceof AbstractBeanDefinition) {
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
}
// The target bean should be ignored in favor of the scoped proxy.
targetDefinition.setAutowireCandidate(false);
targetDefinition.setPrimary(false);
// 注冊(cè)代理前的bean到容器冗茸,在創(chuàng)建代理bean時(shí)候使用.targetBeanName=scopedTarget.lavaPvgInfo
registry.registerBeanDefinition(targetBeanName, targetDefinition);
// 返回代理bean定義作為原來的bean定義
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
2.2 創(chuàng)建代理Bean
先上時(shí)序圖
主要代碼如下:
public void setBeanFactory(BeanFactory beanFactory) {
...
ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
this.scopedTargetSource.setBeanFactory(beanFactory);
//創(chuàng)建代理工廠
ProxyFactory pf = new ProxyFactory();
pf.copyFrom(this);
pf.setTargetSource(this.scopedTargetSource);
...
// Add an introduction that implements only the methods on ScopedObject.
ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));
// Add the AopInfrastructureBean marker to indicate that the scoped proxy
// itself is not subject to auto-proxying! Only its target bean is.
pf.addInterface(AopInfrastructureBean.class);
this.proxy = pf.getProxy(cbf.getBeanClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
....
try {//獲取目標(biāo)類席镀,也就是被代理的
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class[] additionalInterfaces = rootClass.getInterfaces();
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//設(shè)置被代理類為超類,這樣解釋了為啥代理后的類能夠賦值給被代理類不會(huì)發(fā)生錯(cuò)誤
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setInterceptDuringConstruction(false);
//獲取攔截器夏漱,其中就有DynamicAdvisedInterceptor
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
Object proxy;
if (this.constructorArgs != null) {
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
}
else {
proxy = enhancer.create();
}
return proxy;
}
2.3 調(diào)用時(shí)序圖
代碼:
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
...
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 獲取被代理類
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
retVal = methodProxy.invoke(target, args);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
getTarget是關(guān)鍵方法豪诲,看下:
protected Object getTarget() throws Exception {
return this.advised.getTargetSource().getTarget();
}
public Object getTarget() throws Exception {
return getBeanFactory().getBean(getTargetBeanName());
}
所以最后是從IOC獲取目標(biāo)類bean.下面看下getBean代碼:
//獲取RequestScope對(duì)象
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
//調(diào)用RequestScope對(duì)象對(duì)象的get方法
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
requestscope的get方法:
public Object get(String name, ObjectFactory objectFactory) {
//獲取當(dāng)前線程屬性集合
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
Object scopedObject = attributes.getAttribute(name, getScope());
if (scopedObject == null) {//不在屬性集則調(diào)用createBean創(chuàng)建,然后放入集合
scopedObject = objectFactory.getObject();
attributes.setAttribute(name, scopedObject, getScope());
}
return scopedObject;
}
可知requestAttributesHolder屬性是threadlocal
public abstract class RequestContextHolder {
private static final boolean jsfPresent =
ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
new NamedThreadLocal<RequestAttributes>("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
new NamedInheritableThreadLocal<RequestAttributes>("Request context");
}
歡迎關(guān)注微信公眾號(hào):技術(shù)原始積累 獲取更多技術(shù)干貨_