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

📄 mbeanexporter.java

📁 spring的源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		targetSource.setTargetBeanName(beanName);
		targetSource.setBeanFactory(this.beanFactory);

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(targetSource);
		proxyFactory.setProxyTargetClass(true);
		proxyFactory.setFrozen(true);

		Object proxy = proxyFactory.getProxy();
		ObjectName objectName = getObjectName(proxy, beanKey);
		if (logger.isDebugEnabled()) {
			logger.debug("Registering lazy-init MBean [" + objectName + "]");
		}

		ModelMBean mbean = createModelMBean();
		mbean.setModelMBeanInfo(getMBeanInfo(proxy, beanKey));
		mbean.setManagedResource(proxy, MR_TYPE_OBJECT_REFERENCE);

		doRegister(mbean, objectName);
		return objectName;
	}

	/**
	 * Actually registers the MBean with the server. The behavior when encountering
	 * an existing MBean can be configured using the {@link #setRegistrationBehavior(int)}
	 * and {@link #setRegistrationBehaviorName(String)} methods.
	 */
	protected void doRegister(Object mbean, ObjectName objectName) throws JMException {
		try {
			this.server.registerMBean(mbean, objectName);
		}
		catch (InstanceAlreadyExistsException ex) {
			if (this.registrationBehavior == REGISTRATION_IGNORE_EXISTING) {
				if (logger.isDebugEnabled()) {
					logger.debug("Ignoring existing MBean at [" + objectName + "]");
				}
			}
			else if (this.registrationBehavior == REGISTRATION_REPLACE_EXISTING) {
				try {
					if (logger.isDebugEnabled()) {
						logger.debug("Replacing existing MBean at [" + objectName + "]");
					}
					this.server.unregisterMBean(objectName);
					this.server.registerMBean(mbean, objectName);
				}
				catch (InstanceNotFoundException ex2) {
					throw new IllegalStateException(
							"Unable to replace existing MBean at [" + objectName + "]: " + ex.getMessage());
				}
			}
			else {
				throw ex;
			}
		}
	}

	/**
	 * Retrieve the <code>ObjectName</code> for a bean.
	 * <p>If the bean implements the <code>SelfNaming</code> interface, then the
	 * <code>ObjectName</code> will be retrieved using <code>SelfNaming.getObjectName()</code>.
	 * Otherwise, the configured <code>ObjectNamingStrategy</code> is used.
	 * @param bean the name of the bean in the <code>BeanFactory</code>
	 * @param beanKey the key associated with the bean in the beans map
	 * @return the <code>ObjectName</code> for the supplied bean
	 * @throws MalformedObjectNameException if the retrieved <code>ObjectName</code> is malformed.
	 */
	private ObjectName getObjectName(Object bean, String beanKey) throws MalformedObjectNameException {
		if (bean instanceof SelfNaming) {
			return ((SelfNaming) bean).getObjectName();
		}
		else {
			return this.namingStrategy.getObjectName(bean, beanKey);
		}
	}

	/**
	 * Gets the <code>ModelMBeanInfo</code> for the bean with the supplied key
	 * and of the supplied type.
	 */
	private ModelMBeanInfo getMBeanInfo(Object managedBean, String beanKey) throws JMException {
		ModelMBeanInfo info = this.assembler.getMBeanInfo(managedBean, beanKey);
		if (logger.isWarnEnabled() && ObjectUtils.isEmpty(info.getAttributes()) &&
				ObjectUtils.isEmpty(info.getOperations())) {
			logger.warn("Bean with key [" + beanKey +
					"] has been registed as an MBean but has no exposed attributes or operations");
		}
		return info;
	}


	/**
	 * Attempts to detect any beans defined in the <code>ApplicationContext</code> that are
	 * valid MBeans and registers them automatically with the <code>MBeanServer</code>.
	 */
	private void autodetectMBeans() {
		autodetect(new AutodetectCallback() {
			public boolean include(Class beanClass, String beanName) {
				return JmxUtils.isMBean(beanClass);
			}
		});
	}

	/**
	 * Invoked when using an <code>AutodetectCapableMBeanInfoAssembler</code>.
	 * Gives the assembler the opportunity to add additional beans from the
	 * <code>BeanFactory</code> to the list of beans to be exposed via JMX.
	 * <p>This implementation prevents a bean from being added to the list
	 * automatically if it has already been added manually, and it prevents
	 * certain internal classes from being registered automatically.
	 */
	private void autodetectBeans(final AutodetectCapableMBeanInfoAssembler assembler) {
		autodetect(new AutodetectCallback() {
			public boolean include(Class beanClass, String beanName) {
				return assembler.includeBean(beanClass, beanName);
			}
		});
	}

	/**
	 * Performs the actual autodetection process, delegating to an instance
	 * <code>AutodetectCallback</code> to vote on the inclusion of a given bean.
	 * @param callback the <code>AutodetectCallback</code> to use when deciding
	 * whether to include a bean or not
	 */
	private void autodetect(AutodetectCallback callback) {
		String[] beanNames = this.beanFactory.getBeanNamesForType(null);
		for (int i = 0; i < beanNames.length; i++) {
			String beanName = beanNames[i];

			if (!isExcluded(beanName)) {
				Class beanClass = this.beanFactory.getType(beanName);
				if (beanClass != null && callback.include(beanClass, beanName)) {
					boolean lazyInit = isBeanDefinitionLazyInit(this.beanFactory, beanName);
					Object beanInstance = (!lazyInit ? this.beanFactory.getBean(beanName) : null);
					if (!this.beans.containsValue(beanName) &&
							(beanInstance == null || !this.beans.containsValue(beanInstance))) {
						// Not already registered for JMX exposure.
						this.beans.put(beanName, (beanInstance != null ? beanInstance : beanName));
						if (logger.isInfoEnabled()) {
							logger.info("Bean with name '" + beanName + "' has been autodetected for JMX exposure");
						}
					}
					else {
						if (logger.isDebugEnabled()) {
							logger.debug("Bean with name '" + beanName + "' is already registered for JMX exposure");
						}
					}
				}
			}
		}
	}

	/**
	 * Return whether the specified bean definition should be considered as lazy-init.
	 * @param beanFactory the bean factory that is supposed to contain the bean definition
	 * @param beanName the name of the bean to check
	 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#getBeanDefinition
	 * @see org.springframework.beans.factory.config.BeanDefinition#isLazyInit
	 */
	protected boolean isBeanDefinitionLazyInit(ListableBeanFactory beanFactory, String beanName) {
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			return false;
		}
		try {
			BeanDefinition bd = ((ConfigurableListableBeanFactory) beanFactory).getBeanDefinition(beanName);
			return bd.isLazyInit();
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Probably a directly registered singleton.
			return false;
		}
	}

	/**
	 * Create an instance of a class that implements <code>ModelMBean</code>.
	 * <p>This method is called to obtain a <code>ModelMBean</code> instance to
	 * use when registering a bean. This method is called once per bean during the
	 * registration phase and must return a new instance of <code>ModelMBean</code>
	 * @return a new instance of a class that implements <code>ModelMBean</code>
	 * @throws MBeanException if creation of the ModelMBean failed
	 */
	protected ModelMBean createModelMBean() throws MBeanException {
		return new RequiredModelMBean();
	}

	/**
	 * Indicates whether or not a particular bean name is present in the excluded beans list.
	 */
	private boolean isExcluded(String beanName) {
		return (this.excludedBeans != null && this.excludedBeans.contains(beanName));
	}

	/**
	 * Notifies all registered <code>MBeanExporterListener</code> that an MBean
	 * with the supplied <code>ObjectName</code> has been registered.
	 * @param objectName the <code>ObjectName</code> of the registered MBean
	 * @see MBeanExporterListener
	 */
	private void notifyListenersOfRegistration(ObjectName objectName) {
		if (this.listeners != null) {
			for (int i = 0; i < this.listeners.length; i++) {
				MBeanExporterListener listener = this.listeners[i];
				listener.mbeanRegistered(objectName);
			}
		}
	}

	/**
	 * Notifies all registered <code>MBeanExporterListener</code> that an MBean
	 * with the supplied <code>ObjectName</code> has been unregistered.
	 * @param objectName the <code>ObjectName</code> of the registered MBean
	 * @see MBeanExporterListener
	 */
	private void notifyListenersOfUnregistration(ObjectName objectName) {
		if (this.listeners != null) {
			for (int i = 0; i < this.listeners.length; i++) {
				MBeanExporterListener listener = this.listeners[i];
				listener.mbeanUnregistered(objectName);
			}
		}
	}


	/**
	 * Unregisters all beans that this exported has exposed via JMX
	 * when the enclosing <code>ApplicationContext</code> is destroyed.
	 */
	public void destroy() {
		unregisterBeans();
	}

	/**
	 * Unregisters all beans that this exported has exposed via JMX.
	 */
	private void unregisterBeans() {
		logger.info("Unregistering JMX-exposed beans on shutdown");
		for (Iterator it = this.registeredBeans.iterator(); it.hasNext();) {
			ObjectName objectName = (ObjectName) it.next();
			try {
				this.server.unregisterMBean(objectName);
				notifyListenersOfUnregistration(objectName);
			}
			catch (JMException ex) {
				logger.error("Could not unregister MBean [" + objectName + "]", ex);
			}
		}
		this.registeredBeans.clear();
	}


	/**
	 * Internal callback interface for the autodetection process.
	 */
	private static interface AutodetectCallback {

		/**
		 * Called during the autodetection process to decide whether
		 * or not a bean should be include.
		 * @param beanClass the class of the bean
		 * @param beanName the name of the bean
		 */
		boolean include(Class beanClass, String beanName);
	}

}

⌨️ 快捷键说明

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