001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jmx.access; 018 019import org.springframework.aop.framework.ProxyFactory; 020import org.springframework.beans.factory.BeanClassLoaderAware; 021import org.springframework.beans.factory.FactoryBean; 022import org.springframework.beans.factory.InitializingBean; 023import org.springframework.jmx.MBeanServerNotFoundException; 024import org.springframework.util.ClassUtils; 025 026/** 027 * Creates a proxy to a managed resource running either locally or remotely. 028 * The "proxyInterface" property defines the interface that the generated 029 * proxy is supposed to implement. This interface should define methods and 030 * properties that correspond to operations and attributes in the management 031 * interface of the resource you wish to proxy. 032 * 033 * <p>There is no need for the managed resource to implement the proxy interface, 034 * although you may find it convenient to do. It is not required that every 035 * operation and attribute in the management interface is matched by a 036 * corresponding property or method in the proxy interface. 037 * 038 * <p>Attempting to invoke or access any method or property on the proxy 039 * interface that does not correspond to the management interface will lead 040 * to an {@code InvalidInvocationException}. 041 * 042 * @author Rob Harrop 043 * @author Juergen Hoeller 044 * @since 1.2 045 * @see MBeanClientInterceptor 046 * @see InvalidInvocationException 047 */ 048public class MBeanProxyFactoryBean extends MBeanClientInterceptor 049 implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean { 050 051 private Class<?> proxyInterface; 052 053 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 054 055 private Object mbeanProxy; 056 057 058 /** 059 * Set the interface that the generated proxy will implement. 060 * <p>This will usually be a management interface that matches the target MBean, 061 * exposing bean property setters and getters for MBean attributes and 062 * conventional Java methods for MBean operations. 063 * @see #setObjectName 064 */ 065 public void setProxyInterface(Class<?> proxyInterface) { 066 this.proxyInterface = proxyInterface; 067 } 068 069 @Override 070 public void setBeanClassLoader(ClassLoader classLoader) { 071 this.beanClassLoader = classLoader; 072 } 073 074 /** 075 * Checks that the {@code proxyInterface} has been specified and then 076 * generates the proxy for the target MBean. 077 */ 078 @Override 079 public void afterPropertiesSet() throws MBeanServerNotFoundException, MBeanInfoRetrievalException { 080 super.afterPropertiesSet(); 081 082 if (this.proxyInterface == null) { 083 this.proxyInterface = getManagementInterface(); 084 if (this.proxyInterface == null) { 085 throw new IllegalArgumentException("Property 'proxyInterface' or 'managementInterface' is required"); 086 } 087 } 088 else { 089 if (getManagementInterface() == null) { 090 setManagementInterface(this.proxyInterface); 091 } 092 } 093 this.mbeanProxy = new ProxyFactory(this.proxyInterface, this).getProxy(this.beanClassLoader); 094 } 095 096 097 @Override 098 public Object getObject() { 099 return this.mbeanProxy; 100 } 101 102 @Override 103 public Class<?> getObjectType() { 104 return this.proxyInterface; 105 } 106 107 @Override 108 public boolean isSingleton() { 109 return true; 110 } 111 112}