⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptfactorypostprocessor.java

📁 struts+spring 源码 希望能给大家带来帮助
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	public Object postProcessBeforeInstantiation(Class beanClass, String beanName) {
		// We only apply special treatment to ScriptFactory implementations here.
		if (!ScriptFactory.class.isAssignableFrom(beanClass)) {
			return null;
		}

		String scriptedObjectBeanName = SCRIPTED_OBJECT_NAME_PREFIX + beanName;

		// Avoid recreation of the script bean definition in case of a prototype.
		if (!this.scriptBeanFactory.containsBeanDefinition(scriptedObjectBeanName)) {
			RootBeanDefinition bd = this.beanFactory.getMergedBeanDefinition(beanName);

			String scriptFactoryBeanName = SCRIPT_FACTORY_NAME_PREFIX + beanName;
			this.scriptBeanFactory.registerBeanDefinition(
					scriptFactoryBeanName, createScriptFactoryBeanDefinition(bd));
			ScriptFactory scriptFactory =
					(ScriptFactory) this.scriptBeanFactory.getBean(scriptFactoryBeanName, ScriptFactory.class);
			ScriptSource scriptSource =
					convertToScriptSource(scriptFactory.getScriptSourceLocator(), this.resourceLoader);
			Class[] interfaces = scriptFactory.getScriptInterfaces();

			if (scriptFactory.requiresConfigInterface() && !bd.getPropertyValues().isEmpty()) {
				PropertyValue[] pvs = bd.getPropertyValues().getPropertyValues();
				Class configInterface = createConfigInterface(pvs, interfaces);
				interfaces = (Class[]) ObjectUtils.addObjectToArray(interfaces, configInterface);
			}

			RootBeanDefinition objectBd = createScriptedObjectBeanDefinition(
					bd, scriptFactoryBeanName, scriptSource, interfaces);

			long refreshCheckDelay = resolveRefreshCheckDelay(bd);

			if (refreshCheckDelay >= 0) {
				objectBd.setSingleton(false);
			}
			this.scriptBeanFactory.registerBeanDefinition(scriptedObjectBeanName, objectBd);

			if (refreshCheckDelay >= 0) {
				RefreshableScriptTargetSource ts =
						new RefreshableScriptTargetSource(this.scriptBeanFactory, scriptedObjectBeanName, scriptSource);
				ts.setRefreshCheckDelay(refreshCheckDelay);
				return createRefreshableProxy(ts, interfaces);
			}
        }

		return this.scriptBeanFactory.getBean(scriptedObjectBeanName);
	}

	/**
	 * Get the refresh check delay for the given {@link ScriptFactory} {@link BeanDefinition}.
	 * If the {@link BeanDefinition} has a
	 * {@link org.springframework.core.AttributeAccessor metadata attribute}
	 * under the key {@link #REFRESH_CHECK_DELAY_ATTRIBUTE} which is a valid {@link Number}
	 * type, then this value is used. Otherwise, the the {@link #defaultRefreshCheckDelay}
	 * value is used.
	 * @return the refresh check delay
	 */
	protected long resolveRefreshCheckDelay(BeanDefinition bd) {
		long refreshCheckDelay = this.defaultRefreshCheckDelay;
		Object attributeValue = bd.getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
		if (attributeValue instanceof Number) {
			refreshCheckDelay = ((Number) attributeValue).longValue();
		}
		else if (attributeValue instanceof String) {
			refreshCheckDelay = Long.parseLong((String) attributeValue);
		}
		else if (attributeValue != null) {
			throw new BeanDefinitionStoreException(
					"Invalid refresh check delay attribute [" + REFRESH_CHECK_DELAY_ATTRIBUTE +
					"] with value [" + attributeValue + "]: needs to be of type Number or String");
		}
		return refreshCheckDelay;
	}

	/**
	 * Create a ScriptFactory bean definition based on the given script definition,
	 * extracting only the definition data that is relevant for the ScriptFactory
	 * (that is, only bean class and constructor arguments).
	 * @param bd the full script bean definition
	 * @return the extracted ScriptFactory bean definition
	 * @see org.springframework.scripting.ScriptFactory
	 */
	protected RootBeanDefinition createScriptFactoryBeanDefinition(RootBeanDefinition bd) {
		RootBeanDefinition scriptBd = new RootBeanDefinition(bd.getBeanClass());
		scriptBd.getConstructorArgumentValues().addArgumentValues(bd.getConstructorArgumentValues());
		return scriptBd;
	}

	/**
	 * Convert the given script source locator to a ScriptSource instance.
	 * <p>By default, supported locators are Spring resource locations
	 * (such as "file:C:/myScript.bsh" or "classpath:myPackage/myScript.bsh")
	 * and inline scripts ("inline:myScriptText...").
	 * @param scriptSourceLocator the script source locator
	 * @param resourceLoader the ResourceLoader to use (if necessary)
	 * @return the ScriptSource instance
	 */
	protected ScriptSource convertToScriptSource(String scriptSourceLocator, ResourceLoader resourceLoader) {
		if (scriptSourceLocator.startsWith(INLINE_SCRIPT_PREFIX)) {
			return new StaticScriptSource(scriptSourceLocator.substring(INLINE_SCRIPT_PREFIX.length()));
		}
		else {
			return new ResourceScriptSource(resourceLoader.getResource(scriptSourceLocator));
		}
	}

	/**
	 * Create a config interface for the given bean property values.
	 * <p>This implementation creates the interface via CGLIB's InterfaceMaker,
	 * determining the property types from the given interfaces (as far as possible).
	 * @param pvs the bean property values to create a config interface for
	 * @param interfaces the interfaces to check against (might define
	 * getters corresponding to the setters we're supposed to generate)
	 * @return the config interface
	 * @see net.sf.cglib.proxy.InterfaceMaker
	 * @see org.springframework.beans.BeanUtils#findPropertyType
	 */
	protected Class createConfigInterface(PropertyValue[] pvs, Class[] interfaces) {
		Assert.notEmpty(pvs, "Property values must not be empty");
		InterfaceMaker maker = new InterfaceMaker();
		for (int i = 0; i < pvs.length; i++) {
			String propertyName = pvs[i].getName();
			Class propertyType = BeanUtils.findPropertyType(propertyName, interfaces);
			String setterName = "set" + StringUtils.capitalize(propertyName);
			Signature signature = new Signature(setterName, Type.VOID_TYPE, new Type[] {Type.getType(propertyType)});
			maker.add(signature, new Type[0]);
		}
		return maker.create();
	}

	/**
	 * Create a bean definition for the scripted object, based on the given script
	 * definition, extracting the definition data that is relevant for the scripted
	 * object (that is, everything but bean class and constructor arguments).
	 * @param bd the full script bean definition
	 * @return the extracted ScriptFactory bean definition
	 * @see org.springframework.scripting.ScriptFactory#getScriptedObject
	 */
	protected RootBeanDefinition createScriptedObjectBeanDefinition(
			RootBeanDefinition bd, String scriptFactoryBeanName, ScriptSource scriptSource, Class[] interfaces) {

		RootBeanDefinition objectBd = new RootBeanDefinition(bd);
		objectBd.setBeanClass(null);
		objectBd.setFactoryBeanName(scriptFactoryBeanName);
		objectBd.setFactoryMethodName("getScriptedObject");
		objectBd.getConstructorArgumentValues().clear();
		objectBd.getConstructorArgumentValues().addIndexedArgumentValue(0, scriptSource);
		objectBd.getConstructorArgumentValues().addIndexedArgumentValue(1, interfaces);
		return objectBd;
	}

	/**
	 * Create a refreshable proxy for the given AOP TargetSource.
	 * @param ts the refreshable TargetSource
	 * @param interfaces the proxy interfaces (may be <code>null</code> to
	 * indicate proxying of all interfaces implemented by the target class)
	 * @return the generated proxy
	 * @see RefreshableScriptTargetSource
	 */
	protected Object createRefreshableProxy(TargetSource ts, Class[] interfaces) {
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(ts);

		if (interfaces == null) {
			interfaces = ClassUtils.getAllInterfacesForClass(ts.getTargetClass());
		}
		proxyFactory.setInterfaces(interfaces);

		DelegatingIntroductionInterceptor introduction = new DelegatingIntroductionInterceptor(ts);
		introduction.suppressInterface(TargetSource.class);
		proxyFactory.addAdvice(introduction);

		return proxyFactory.getProxy();
	}


	/**
	 * Destroy the inner bean factory (used for scripts) on shutdown.
	 */
	public void destroy() {
		this.scriptBeanFactory.destroySingletons();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -