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

📄 proxyfactorybean.java

📁 spring的源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

	private synchronized Object newPrototypeInstance() {
		refreshAdvisorChain();
		refreshTarget();
		// In the case of a prototype, we need to give the proxy
		// an independent instance of the configuration.
		if (logger.isDebugEnabled()) {
			logger.debug("Creating copy of prototype ProxyFactoryBean config: " + this);
		}
		AdvisedSupport copy = new AdvisedSupport();
		copy.copyConfigurationFrom(this);
		if (logger.isDebugEnabled()) {
			logger.debug("Copy has config: " + copy);
		}
		return copy.createAopProxy().getProxy();
	}

	/**
	 * Create the advisor (interceptor) chain. The advisors that are sourced
	 * from a BeanFactory will be refreshed each time a new prototype instance
	 * is added. Interceptors added programmatically through the factory API
	 * are unaffected by such changes.
	 */
	private void createAdvisorChain() throws AopConfigException, BeansException {
		if (this.interceptorNames == null || this.interceptorNames.length == 0) {
			return;
		}
		
		// Globals can't be last
		if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX)) {
			throw new AopConfigException("Target required after globals");
		}

		// Materialize interceptor chain from bean names
		for (int i = 0; i < this.interceptorNames.length; i++) {
			String name = this.interceptorNames[i];
			logger.debug("Configuring interceptor '" + name + "'");

			if (name.endsWith(GLOBAL_SUFFIX)) {
				if (!(this.beanFactory instanceof ListableBeanFactory)) {
					throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");
				}
				else {
					addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
					                 name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
				}
			}
			else {
				// add a named interceptor
				Object advice = this.beanFactory.getBean(this.interceptorNames[i]);
				addAdvisor(advice, this.interceptorNames[i]);
			}
		}
	}

	/**
	 * Refresh named beans from the interceptor chain.
	 * We need to do this every time a new prototype instance is returned,
	 * to return distinct instances of prototype interfaces and pointcuts.
	 */
	private void refreshAdvisorChain() {
		Advisor[] advisors = getAdvisors();
		for (int i = 0; i < advisors.length; i++) {
			String beanName = (String) this.sourceMap.get(advisors[i]);
			if (beanName != null) {
				logger.info("Refreshing bean named '" + beanName + "'");
				Object bean = this.beanFactory.getBean(beanName);
				Object refreshedAdvisor = namedBeanToAdvisorOrTargetSource(bean);
				// might have just refreshed target source
				if (refreshedAdvisor instanceof Advisor) {
					// What about aspect interfaces!? we're only updating
					replaceAdvisor(advisors[i], (Advisor) refreshedAdvisor);
				}
				else {
					setTargetSource((TargetSource) refreshedAdvisor);
				}
				// keep name mapping up to date
				this.sourceMap.put(refreshedAdvisor, beanName);
			}
			else {
				// We can't throw an exception here, as the user may have added additional
				// pointcuts programmatically we don't know about
				logger.info("Cannot find bean name for Advisor [" + advisors[i] + 
					"] when refreshing advisor chain");
			}
		}
	}

	/**
	 * Add all global interceptors and pointcuts.
	 */
	private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
		String[] globalAdvisorNames = BeanFactoryUtils.beanNamesIncludingAncestors(beanFactory, Advisor.class);
		String[] globalInterceptorNames = BeanFactoryUtils.beanNamesIncludingAncestors(beanFactory, Interceptor.class);
		List beans = new ArrayList(globalAdvisorNames.length + globalInterceptorNames.length);
		Map names = new HashMap();
		for (int i = 0; i < globalAdvisorNames.length; i++) {
			String name = globalAdvisorNames[i];
			Object bean = beanFactory.getBean(name);
			beans.add(bean);
			names.put(bean, name);
		}
		for (int i = 0; i < globalInterceptorNames.length; i++) {
			String name = globalInterceptorNames[i];
			Object bean = beanFactory.getBean(name);
			beans.add(bean);
			names.put(bean, name);
		}
		Collections.sort(beans, new OrderComparator());
		for (Iterator it = beans.iterator(); it.hasNext();) {
			Object bean = it.next();
			String name = (String) names.get(bean);
			if (name.startsWith(prefix)) {
				addAdvisor(bean, name);
			}
		}
	}

	/**
	 * Add the given interceptor, pointcut or object to the interceptor list.
	 * Because of these three possibilities, we can't type the signature
	 * more strongly.
	 * @param next interceptor, pointcut or target object.
	 * @param name bean name from which we obtained this object in our owning
	 * bean factory
	 */
	private void addAdvisor(Object next, String name) {
		logger.debug("Adding advisor or TargetSource [" + next + "] with name [" + name + "]");
		// We need to add a method pointcut so that our source reference matches
		// what we find from superclass interceptors.
		Object advisor = namedBeanToAdvisorOrTargetSource(next);
		if (advisor instanceof Advisor) {
			// if it wasn't just updating the TargetSource
			logger.debug("Adding advisor with name [" + name + "]");
			addAdvisor((Advisor) advisor);
			// Record the pointcut as descended from the given bean name.
			// This allows us to refresh the interceptor list, which we'll need to
			// do if we have to create a new prototype instance. Otherwise the new
			// prototype instance wouldn't be truly independent, because it might
			// reference the original instances of prototype interceptors.
			this.sourceMap.put(advisor, name);
		}
		else {
			logger.debug("Adding TargetSource [" + advisor + "] with name [" + name + "]");
			setTargetSource((TargetSource) advisor);
			// save target name
			this.targetName = name;
		}
	}
	
	private void refreshTarget() {
		logger.debug("Refreshing target with name '" + this.targetName + "'");
		if (this.targetName == null) {
			throw new AopConfigException("Target name cannot be null when refreshing!");
		}
		Object target = this.beanFactory.getBean(this.targetName);
		setTarget(target);
	}

	/**
	 * Return Advisor or TargetSource.
	 */
	private Object namedBeanToAdvisorOrTargetSource(Object next) {
		try {
			Advisor adv = GlobalAdvisorAdapterRegistry.getInstance().wrap(next);
			return adv;
		}
		catch (UnknownAdviceTypeException ex) {
			// TODO consider checking that it's the last in the list?
			if (next instanceof TargetSource) {
				return (TargetSource) next;
			}
			else {
				// It's not a pointcut or interceptor.
				// It's a bean that needs an invoker around it.
				return new SingletonTargetSource(next);
			}
		}
	}


	/**
	 * @see org.springframework.aop.framework.AdvisedSupportListener#activated(org.springframework.aop.framework.AdvisedSupport)
	 */
	public void activated(AdvisedSupport advisedSupport) {
	}

	/**
	 * Blow away and recache singleton to allow for advice changes.
	 * @see org.springframework.aop.framework.AdvisedSupportListener#adviceChanged(org.springframework.aop.framework.AdvisedSupport)
	 */
	public void adviceChanged(AdvisedSupport advisedSupport) {
		logger.info("Advice has changed; recaching singleton instance");
		this.singletonInstance = null;
		getSingletonInstance();
	}

}

⌨️ 快捷键说明

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